将 no-cors 包含在标头中以获取 react.js 中的 json 内容时出现奇怪的错误

Posted

技术标签:

【中文标题】将 no-cors 包含在标头中以获取 react.js 中的 json 内容时出现奇怪的错误【英文标题】:strange error when including no-cors into header for fetch of json content in a react.js 【发布时间】:2017-07-09 14:35:13 【问题描述】:

我对反应很陌生,对 nodeJS 也很陌生。我正在尝试测试如何从我的 nodeJS 网络服务中提取 json 数据并在反应中呈现它。 我只处于测试阶段,但正在努力理解这个问题是什么。我可以通过以下方式从演示作业 json 资源中获取内容:

let url = "http://codepen.io/jobs.json";
let iterator = fetch(url);
  iterator
    .then(response => response.json())
    .then(post => alert(post.jobs[3].company_name));
   

但我自己的 JSON 资源位于 http://localhost:8888 - 所以我知道我需要在标头中设置 no-cors 以允许跨站点资源,因此我尝试过对我自己的资源进行解释:

let url = "http://codepen.io/jobs.json";
let iterator = fetch(url, mode: 'no-cors');
  iterator
    .then(response => response.json())
    .then(post => alert(post.jobs[3].company_name));
   

但这给了我一个错误:resonse.json() 行上的"Uncaught (in promise) SyntaxError: Unexpected end of input"

有什么想法吗?总而言之,我真的很感激一些更广泛的反应代码来获取作业列表,将其添加到组件状态,然后渲染列表 - 沿着以下行:

componentDidMount() 
  let url = "http://codepen.io/jobs.json";
  let iterator = fetch(url, method: 'GET', mode: 'no-cors');
  iterator
    .then(response => response.json())
    .then(post => alert(post.jobs[3].company_name));
 

render()         
    return(
        <div>
            <div>Items:</div>
            <div>this.state.items.map etc</div>
        </div>  
    );

【问题讨论】:

【参考方案1】:

您从 codepen 获得的响应类型为:'cors',但您提供的是 mode:no-cors,服务器需要发送所需的 CORS 标头才能访问响应。

componentDidMount() 
   let url = "https://codepen.io/jobs.json";
   let iterator = fetch(url, method: 'GET', mode: 'cors');
   iterator
     .then(response => 
       console.log('sss', response)
       return response.json();
     )
     .then(post => alert(post.jobs[3].company_name));
   

render()         
  return(
      <div>
        <div>Items:</div>
           <div>this.state.items.map etc</div>
        </div>  
    );

【讨论】:

非常感谢 p0k8!我认为这来自于我对 CORS 的有限了解!所以我猜 CORS 标头标志需要匹配。因此,如果我将其切换到我的localhost:8888,我需要编写一个匹配的标题(cors 或 no-cors?)。我的 nodeJS 网络服务目前只是一个针对 postgres 的超级基本查询:以输出行结尾: res.json(content);我不认为你可以建议如何在这里更改标题? :) 再次感谢! 我猜你什么都不用做,cors 被允许提供对另一个域的访问。 codepen启用了cors,这意味着任何人都可以请求数据,关于CORS还有很多要了解maxcdn.com/one/visual-glossary/cors 如果其他域应用程序试图访问您的localhost:8888,您必须使用cors 中间件来允许访问基本上我们的应用程序会检查Origin 标头类型,如果它没有t 匹配到我们的域localhost:8888,那么它会抛出一个 cors 错误 再次感谢 pok8。我在我的 Express webservice 响应中添加了以下内容,对其进行了排序://您希望允许连接的网站 res.setHeader('Access-Control-Allow-Origin', 'localhost:3000'); // 你希望允许的请求方法 res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // 如果您需要网站在请求中包含 cookie,则设置为 true res.setHeader('Access-Control-Allow-Credentials', true); 是的,你必须这样做,或者在 npmjs.com 中有一个 cors 包,安装它并用作中间件,一些小代码,codepen 的类型是 cors 所以模式应该be -- 模式:'cors'【参考方案2】:

只是为了让答案的 cmets 中的代码更清晰一些。 pOk8 发现了这个问题。用我的外行术语来说,我需要更改我的 localhost Web 服务的标头以启用 react fetch 工作。这是我添加给我的 nodeJS express 服务标头:

// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);

希望这是有道理的。

【讨论】:

以上是关于将 no-cors 包含在标头中以获取 react.js 中的 json 内容时出现奇怪的错误的主要内容,如果未能解决你的问题,请参考以下文章

当使用 mode: no-cors 请求时,浏览器没有添加我在前端代码中设置的请求标头

使用带有模式的 fetch API:'no-cors',无法设置请求标头

对 Flask 后端响应正文的获取请求为 null 且没有 cors 并且在没有 no-cors 的情况下失败

如何修复“将请求的模式设置为'no-cors'”错误?

React hooks useEffect fetch CORS 问题

从 ASP.NET CORE Web Api 获取 React 中的特定响应标头(例如,Content-Disposition)