【问题标题】:Uncaught (in promise) TypeError: Failed to fetch and Cors errorUncaught (in promise) TypeError: Failed to fetch and Cors error
【发布时间】:2017-08-02 22:09:47
【问题描述】:

从数据库取回数据时遇到问题。我正在尽力解释问题。

1.如果我在下面的代码中保留“mode”:“no-cors”,那么我可以使用 Postman 从服务器获取数据,但不能从我自己的服务器获取数据。认为它必须是我的客户端错误

  1. 当我删除 "mode":"no-cors" 时出现 2 个错误: -Fetch API 无法加载http://localhost:3000/。 Access-Control-Allow-Headers 在预检响应中不允许请求标头字段 access-control-allow-origin。 -Uncaught (in promise) TypeError: Failed to fetch

Quick Browsing 建议输入 "mode":"no-cors" 以修复此错误,但感觉不对。

所以我想也许有人对如何解决这个问题提出了建议。

真的希望我足够清楚,但我很确定我在这里没有给出明确的解释:S

function send(){
    var myVar = {"id" : 1};
    console.log("tuleb siia", document.getElementById('saada').value);
    fetch("http://localhost:3000", {
        method: "POST",
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Content-Type": "text/plain"
        },//"mode" : "no-cors",
        body: JSON.stringify(myVar)
        //body: {"id" : document.getElementById('saada').value}
    }).then(function(muutuja){

        document.getElementById('väljund').innerHTML = JSON.stringify(muutuja);
    });
}

【问题讨论】:

  • mode: no-cors 将保证无法访问响应。此外,您在代码中使用了 fetch wrong ...,参数 muutuja 是一个 Response 对象,要获取 json,您需要 return muutuja.json() 然后在 next 中,参数将是您想要的数据
  • 使用 CORS 的简单答案 ...服务器需要允许访问其资源,因此服务器需要适当地发出 CORS 标头 - 因此请求中的 "Access-Control-Allow-Origin": "*" 毫无意义(并将触发添加到并发症的预检请求) - 如果 CORS 能够被客户端“绕过”,那么 CORS 将 100% 毫无意义
  • 我会看看我是否能够正确获取 @JaromandaX 在本地完成这一切 在我的服务器的 js 代码 res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type');
  • 哦,所以您确实发出了 CORS 响应标头...您的服务器是否通过添加“非标准”标头来处理您触发的 OPTIONS 飞行前?我认为,如果您从 request 中删除访问控制标头并且 不要mode: 'no-cors' 添加到请求中,我认为您的所有问题都会消失
  • @JaromandaX 成功了!!!我确实从 send() 中删除了访问控制,还删除了 mode:'no-cors' 似乎现在效果很好

标签: javascript node.js cors


【解决方案1】:

在请求头中添加mode:'no-cors'保证响应中不会有响应

添加“非标准”标头,'access-control-allow-origin' 行将触发 OPTIONS 预检请求,您的服务器必须正确处理该请求才能发送 POST 请求

您还做错了fetch ... fetchResponse 对象返回一个“承诺”,该对象具有jsontext 等的承诺创建者,具体取决于内容类型。 ..

简而言之,如果您的服务器端正确处理 CORS(您的评论表明确实如此),则以下内容应该可以工作

function send(){
    var myVar = {"id" : 1};
    console.log("tuleb siia", document.getElementById('saada').value);
    fetch("http://localhost:3000", {
        method: "POST",
        headers: {
            "Content-Type": "text/plain"
        },
        body: JSON.stringify(myVar)
    }).then(function(response) {
        return response.json();
    }).then(function(muutuja){
        document.getElementById('väljund').innerHTML = JSON.stringify(muutuja);
    });
}

但是,由于您的代码对 JSON 并不真正感兴趣(毕竟它会将对象字符串化) - 这样做更简单

function send(){
    var myVar = {"id" : 1};
    console.log("tuleb siia", document.getElementById('saada').value);
    fetch("http://localhost:3000", {
        method: "POST",
        headers: {
            "Content-Type": "text/plain"
        },
        body: JSON.stringify(myVar)
    }).then(function(response) {
        return response.text();
    }).then(function(muutuja){
        document.getElementById('väljund').innerHTML = muutuja;
    });
}

【讨论】:

  • 非常感谢。事情开始朝着某个方向发展!!也许您也可以帮助我解决来自服务器的“db”响应。我将在下一条评论中描述我遇到的问题
  • 为什么不问一个新问题呢? (在搜索 SO 以查看是否已经有答案 :p )
  • 好的,非常感谢。我会试着摆弄一下当前的事情,如果仍然卡住,然后发布一个新问题。
【解决方案2】:

就我而言,问题在于协议。我试图用http 而不是https 调用脚本网址。

【讨论】:

    【解决方案3】:

    请参阅mozilla.org's write-up,了解 CORS 的工作原理。

    您需要您的服务器发回正确的响应标头,例如:

    Access-Control-Allow-Origin: http://foo.example
    Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS
    Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
    

    请记住,您可以将"*" 用于Access-Control-Allow-Origin,这仅在您尝试传递身份验证数据时才有效。在这种情况下,您需要明确列出要允许的源域。要允许多个域,请参阅this post

    【讨论】:

      【解决方案4】:

      试试这个

       await fetch(url, {
            mode: 'no-cors'
       })
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      【解决方案5】:

      您可以在不添加“Access-Control-Allow-Origin”:“*”的情况下使用解决方案,如果您的服务器已经使用代理网关,则不会发生此问题,因为前端和后端将在相同的 IP 和端口中路由在客户端,但对于开发,如果您不需要额外的代码,则需要这三个解决方案之一 1- 使用代理服务器模拟真实环境,将前后端配置在同一个端口

      2- 如果您使用 Chrome,您可以使用名为 Allow-Control-Allow-Origin 的扩展程序:* 它将帮助您避免此问题

      3- 您可以使用代码,但某些浏览器版本可能不支持,因此请尝试使用以前的解决方案之一

      最好的解决方案是使用像ngnix 这样的代理,它易于配置,并且可以模拟生产部署的真实情况

      【讨论】:

        猜你喜欢
        • 2018-04-03
        • 2020-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-28
        相关资源
        最近更新 更多