Bootstrap

fetch为什么加了允许跨域请求mode: ‘no-cors‘,添加的多个header就丢失了?

当你在 fetch 请求中设置 mode: 'no - cors' 时,添加的多个自定义请求头会丢失,这主要是由 CORS(跨域资源共享)机制和 no - cors 模式的特性决定的。下面为你详细解释:

1. CORS 机制概述

CORS 是一种现代浏览器的安全机制,用于控制跨域请求。当浏览器发起跨域请求时,会根据请求的类型(简单请求或预检请求)和服务器端的配置来决定是否允许该请求。简单请求通常可以直接发送,而预检请求(复杂请求)会先发送一个 OPTIONS 请求到服务器,以确认服务器是否允许该请求。

2. no - cors 模式的特性

no - cors 模式是 fetch API 提供的一种特殊模式,其设计目的是允许浏览器发起一些简单的跨域请求,而无需进行复杂的 CORS 预检请求。不过,这种模式也有一些严格的限制:

  • 请求方法限制:只允许使用 GETHEAD 或 POST 方法。
  • 请求头限制:只允许使用所谓的 “简单请求头”。简单请求头包括:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(但值只能是 application/x-www-form-urlencodedmultipart/form-data 或 text/plain

3. 自定义请求头丢失的原因

当你设置 mode: 'no - cors' 时,浏览器会严格遵循上述规则。如果你添加了除简单请求头之外的自定义请求头(如 AuthorizationCustom - Header 等),浏览器会忽略这些自定义请求头,以确保请求符合 no - cors 模式的要求。这是为了避免违反 CORS 机制,防止在不进行预检请求的情况下发送可能不安全的跨域请求。

示例代码说明

收起javascript

fetch('https://example.com', {
    mode: 'no-cors',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer your_token_here',
        'Custom-Header': 'Custom Value'
    }
})
  .then(response => {
        console.log(response);
    })
  .catch(error => {
        console.error(error);
    });

在这个例子中,Authorization 和 Custom - Header 这些自定义请求头会被浏览器忽略,因为它们不属于简单请求头,而 Content - Type: application/json 也不符合 no - cors 模式下 Content - Type 的允许值范围,所以实际上浏览器只会发送符合简单请求头规则的请求头。

解决方案

  • 如果需要自定义请求头:不要使用 no - cors 模式。可以尝试使用 cors 模式(默认值),并确保服务器端正确配置了 CORS 头,以允许跨域请求和自定义请求头。
  • 如果不需要读取响应内容:可以继续使用 no - cors 模式,但要避免添加自定义请求头,只使用简单请求头。
;