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

Posted

技术标签:

【中文标题】当使用 mode: no-cors 请求时,浏览器没有添加我在前端代码中设置的请求标头【英文标题】:When using mode: no-cors for a request, browser isn’t adding request header I’ve set in my frontend code 【发布时间】:2017-11-28 14:16:05 【问题描述】:

在我的 React 应用程序中,我有以下 API POST 以允许用户编辑他们的个人资料(名称和图像)。

  static updateProfile(formData, user_id) 
    const request = new Request(`http://localhost:4300/api/v1/profiles/$user_id`, 
      headers: new Headers(
        'Authorization': getBearerToken()
      ),
      mode: 'no-cors',
      method: "POST",
      body: formData
    );

    return fetch(request).then(response => 
      return response.json();
    ).catch(error => 
      return error;
    );
  

上面的问题是带有授权令牌的标头没有在 POST 中发送...

如何在上面的 fetch 请求中获取要发送的 Authorization 标头?

仅供参考,对于非多部分表单,授权令牌已成功发送,如下所示:

  static loadProfile(user_id) 
    const request = new Request(`http://localhost:4300/api/v1/profiles/$user_id`, 
      headers: new Headers(
        'Authorization': getBearerToken(),
        'Accept'       : 'application/json',
        'Content-Type' : 'application/json',
      )
    );

    return fetch(request).then(response => 
      return response.json();
    ).catch(error => 
      return error;
    );
  

【问题讨论】:

【参考方案1】:

如果您设置了任何特殊的请求标头,则不能使用no-cors 模式,因为将其用于请求的效果之一是它告诉浏览器不允许您的前端 javascript 代码设置除 @ 之外的任何请求标头987654321@。见the spec requirements:

要将 name/value 对附加到 Headers 对象 (headers),请运行以下步骤:

    否则,如果 guard 是 "request-no-cors" 并且 name/value 不是 CORS-safelisted request-header,则返回。

在该算法中,return 等同于“在不将该标头添加到 Headers 对象的情况下返回”。

Authorization 不是CORS-safelisted request-header,因此如果您使用mode: 'no-cors' 进行请求,您的浏览器将不允许您设置。 Content-Type: application/json 也一样。

如果您尝试使用no-cors 模式的原因是为了避免在不使用时出现的其他问题,则解决方案是解决其他问题的根本原因。因为无论您试图解决什么问题,mode: 'no-cors' 最终都不会成为解决方案。它只会产生不同的问题,比如你现在遇到的问题。

【讨论】:

我可以重新启用 cors,然后将 header 与 w 多部分表单数据一起发送吗? 是的,您应该可以删除mode: 'no-cors' 并提出请求。如果这样做时您收到一些不同的错误消息,那么您可能想要更新您的问题以包含您在没有 mode: 'no-cors' 的情况下收到的任何其他错误消息,然后我们可以尝试找到该问题的解决方案。【参考方案2】:

通过使用下面的代码,您可以使用 Authorization 或 Bearer 发出 fetch 请求

    var url = "https://yourUrl";
    var bearer = 'Bearer '+ bearer_token;
    fetch(url, 
    method: 'GET',
    withCredentials: true,
    credentials: 'include',
    headers: 
        'Authorization': bearer,
        'X-FP-API-KEY': 'iphone',
        'Content-Type': 'application/json'
    ).then((responseJson) => 
        var items = JSON.parse(responseJson._bodyInit);
    )
    .catch(error => this.setState(
    isLoading: false,
    message: 'Something bad happened ' + error
    ));

【讨论】:

以上是关于当使用 mode: no-cors 请求时,浏览器没有添加我在前端代码中设置的请求标头的主要内容,如果未能解决你的问题,请参考以下文章

Fetch API 默认跨域行为

获取令牌 oauth2 - POST 客户端数据 - 错误请求

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

在将模式设置为“no-cors”时使用 fetch 访问 API 时出错 [重复]

如何在 fetch() 中使用 no-cors

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