Javascript Uncaught (in promise) TypeError: Failed to fetch and Cors error

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42754388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:24:41  来源:igfitidea点击:

Uncaught (in promise) TypeError: Failed to fetch and Cors error

javascriptnode.jscors

提问by OFFLlNE

having a problem with getting data back from database. I am trying my best to explain the problem.

从数据库取回数据时出现问题。我正在尽力解释这个问题。

1.If I leave "mode":"no-cors" inside the code below, then I can get data back from server with Postman, but not with from my own server. Thinking it has to be my client side error

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

  1. When I remove "mode":"no-cors" then I am getting 2 errors: -Fetch API cannot load http://localhost:3000/. Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response. -Uncaught (in promise) TypeError: Failed to fetch
  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 suggested to put in the "mode":"no-cors" which fixed this error, but it does not feel right thing to do.

Quick Browsing 建议放入 "mode":"no-cors" 以修复此错误,但感觉这样做并不正确。

So I thought maybe somebody has a suggestion how to approach this problem.

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

Really hope I was clear enough, but pretty sure I am not giving clear explanation here :S

真的希望我足够清楚,但很确定我没有在这里给出明确的解释: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);
    });
}

采纳答案by Jaromanda X

Adding mode:'no-cors'to the request header guarantees that no response will be available in the response

添加mode:'no-cors'到请求标头可确保响应中没有可用响应

Adding a "non standard" header, line 'access-control-allow-origin'will trigger a OPTIONS preflight request, which your server must handle correctly in order for the POST request to even be sent

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

You're also doing fetchwrong ... fetchreturns a "promise" for a Responseobject which has promise creators for json, text, etc. depending on the content type...

你也做fetch不对......fetch返回了一个“承诺”Response这对于承诺的创造者对象jsontext等等。根据内容类型...

In short, if your server side handles CORS correctly (which from your comment suggests it does) the following should work

简而言之,如果您的服务器端正确处理 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);
    });
}

however, since your code isn't really interested in JSON (it stringifies the object after all) - it's simpler to do

但是,由于您的代码对 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;
    });
}

回答by Dave Cole

See mozilla.org's write-upon how CORS works.

请参阅mozilla.org关于 CORS 工作原理的文章。

You'll need your server to send back the proper response headers, something like:

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

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

Bear in mind you can use "*"for Access-Control-Allow-Originthat will only work if you're trying to pass Authentication data. In that case, you need to explicitly list the origin domains you want to allow. To allow multiple domains, see this post

请记住,你可以使用"*"Access-Control-Allow-Origin将,如果你想通过认证的数据只有工作。在这种情况下,您需要明确列出要允许的源域。要允许多个域,请参阅此帖子

回答by IgniteCoders

In my case, the problem was the protocol. I was trying to call a script url with httpinstead of https.

就我而言,问题在于协议。我试图用http而不是https.

回答by 3alaa baiomy

you can use solutions without adding "Access-Control-Allow-Origin": "*", if your server is already using Proxy gateway this issue will not happen because the front and backend will be route in the same IP and port in client side but for development, you need one of this three solution if you don't need extra code 1- simulate the real environment by using a proxy server and configure the front and backend in the same port

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

2- if you using Chrome you can use the extension called Allow-Control-Allow-Origin: * it will help you to avoid this problem

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

3- you can use the code but some browsers versions may not support that so try to use one of the previous solutions

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

the best solution is using a proxy like ngnixits easy to configure and it will simulate the real situation of the production deployment

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