【问题标题】:ES6 isomorphic-fetch does not send headersES6 isomorphic-fetch 不发送标头
【发布时间】:2017-02-04 20:40:45
【问题描述】:

我正在开发我的第一个基于 React 的前端应用程序。此应用程序的目的是连接到 RESTful API 以获取和发布数据。问题是我无法发送令牌标头以通过安全检查,因此请求失败。

我得到不同的错误取决于我使用的浏览器。

这是我的 main.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import promise from 'es6-promise';
import 'isomorphic-fetch';

promise.polyfill();

class Employee extends React.Component {

  constructor(props){
    super(props);
    this.state = {employees : []};
  }

  componentWillMount(){
    fetch('http://localhost:8080/app/rest/employees',{ method: 'get', headers: {'Access-Control-Allow-Origin': 'http://localhost:8080', 'Content-Type': 'x-www-form-urlencoded', 'token' : '93edf459ba78d13be0e9d21143238f43796de1f6ebbc58b133af7f33b8222676'}})
      .then((response) => {
        return response.json();
      })
      .then((downscalings) => {
        this.setState({ employees: values });
      })
  }

  update(){
    this.setState({name : 'John'});
  }

  render(){
    return <div>
        <input type="text" value="aaaa"></input>
        <button onClick={this.update}>Set name</button>
      </div>
  }
}

ReactDOM.render(
  <Employee/>,
  document.getElementById('container')
);

这是来自浏览器的输出日志错误:

Failed to load resource: the server responded with a status of 401 (No Autorizado)
index.html:1 Fetch API cannot load http://localhost:8080/app/rest/employees. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
index.html:1 Uncaught (in promise) TypeError: Failed to fetch(…)

这是网络跟踪:

获取员工

本地主机:8080

0 乙

OPTIONS 员工

401 未授权

本地主机:8080

37 乙

我假设没有发送标头,因此 REST 服务拒绝该请求。由于警告,我还添加了 CORS 标头。我做错了什么?

【问题讨论】:

  • 后端需要token的方式
  • 能否请您显示浏览器记录的网络调用的请求标头和响应标头?
  • @Aatif Bandey 后端从标头“token”中获取令牌。我认为它隐含在我展示的代码中。
  • 您在网络选项卡中看到的我的意思是方法是OPTIONS 或POST
  • Access-Control-Allow-Origin 是在您的 OPTIONS 请求之后发送的响应标头。您应该配置后端服务器 CORS 以允许来自前端的请求。你用什么后端?

标签: reactjs cors es6-promise


【解决方案1】:

我将回答我自己的答案。感谢@cema-sp 提供了发现发生了什么的关键。

这里的问题与我的 Spring 项目中的 CORS 配置有关。这个 Spring 项目公开了一个基于令牌安全性的 REST API。它有两个问题:

1-OPTIONS 请求被安全令牌过滤器阻止:

我不知道 CORS 的工作原理。 CORS,即跨域资源共享,定义了一种启用客户端跨域请求的机制。 CORS 被 FireFox、Chrome、Safari 和 IE 等现代浏览器广泛支持。如果您只是运行我的 fetch 并调用后端,您可能会注意到 GET 请求已更改为 OPTIONS 并且有一个 GET 请求正在等待(您可以在我的初始帖子中看到该图像)。浏览器向服务器发送一个 OPTIONS 请求,服务器需要发送带有正确标头的响应。因此,您需要将这些标头添加到 OPTIONS 请求中。

在响应中,您必须包含前端应用程序可用的标头。就我而言,我添加了令牌标头来验证请求。如果您使用的是 spring 3.1,则需要创建一个像这样的过滤器:

public class CORSFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                                    throws ServletException, IOException {

        response.addHeader("Access-Control-Allow-Origin", "*");

        if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type, token");
            response.addHeader("Access-Control-Max-Age", "1");// 30 min
        }
        filterChain.doFilter(request, response);
    }
}

然后将其添加到 web.xml

<filter>
    <filter-name>cors</filter-name>
    <filter-class>es.predictia.dp.web.security.CORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>cors</filter-name>
    <url-pattern>/rest/*</url-pattern>
</filter-mapping>

如果您使用的是 spring 4,请查看此帖子 https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

2-它正在重置所有响应以避免将 jsessionid 注入响应中。现在我直接删除 set-cookie。

谢谢大家

【讨论】:

    猜你喜欢
    • 2018-01-17
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 2016-10-22
    • 2020-08-12
    • 2018-02-21
    相关资源
    最近更新 更多