fetch() 不发送 headers?

fetch() does not send headers?

我正在从浏览器发送 POST 请求:

fetch(serverEndpoint, {
    method: 'POST',
    mode: 'no-cors', // this is to prevent browser from sending 'OPTIONS' method request first
    redirect: 'follow',
    headers: new Headers({
            'Content-Type': 'text/plain',
            'X-My-Custom-Header': 'value-v',
            'Authorization': 'Bearer ' + token,
    }),
    body: companyName
})

当请求到达我的 back-end 时,它既不包含 X-My-Custom-Header 也不包含 Authorization header。

我的 back-end 是 Google Firebase 的云函数(基本上只是 Node.js 端点),看起来像这样:

exports.createCompany = functions.https.onRequest((req, res) => {
    let headers = ['Headers: ']
    for (let header in req.headers) {
        headers.push(`${header} : ${req.headers[header]}`)
    }
    console.log(headers)
    ...
}

该 Google Cloud for Firebase 函数的控制台日志不包含任何 X-My-Custom-HeaderAuthorization header。

怎么了?


编辑 1

所以在 Chrome 中使用开发工具检查了 X-My-Custom-HeaderAuthorization header 都不是从浏览器发送的...现在的问题是:为什么?我该如何解决?


编辑 2

关于我的应用程序的更多信息:它是 React 应用程序。我禁用了服务人员。我尝试创建 Request 并使用 req.headers.append() 专门添加 header。 headers 仍然不会发送。

same-origin policy 限制了网页可以从其他源发送到资源的请求类型。

仅在no-corsmode, the browser is limited to sending “simple” requests — those with safelisted methods and safelisted headers中。

要发送带有 headers 的 cross-origin 请求,例如 AuthorizationX-My-Custom-Header,您必须放弃 no-cors 模式并支持预检请求(OPTIONS).

“简单”和“non-simple”请求之间的区别是出于历史原因。网页总是可以通过各种方式(例如创建和提交表单)执行一些 cross-origin 请求,因此当 Web 浏览器引入一种发送 cross-origin 请求(cross-origin resource sharing 或 CORS)的原则性方式时),决定此类“简单”请求可以免除预检 OPTIONS 检查。

你能试试这个吗?

fetch(serverEndpoint, {  
  credentials: 'include'  
})

参考。 https://developers.google.com/web/updates/2015/03/introduction-to-fetch#sending_credentials_with_a_fetch_request

1st:当您在 exports.createCompany 函数中调用 headers 时,您的 let headers = ['Headers: '] 是大写的 H 而不是小写的 h 这可能会导致错误。 headers 中的标记后还有一个逗号,不应该在那里。

第二:每次我在 React Native 中使用获取请求时,header: 不需要 new Headers

试试这个:

fetch(serverEndpoint, {
    method: 'POST',
    mode: 'no-cors',
    redirect: 'follow',
    headers:{
      'Content-Type': 'text/plain',
      'X-My-Custom-Header': 'value-v',
      'Authorization': 'Bearer ' + token
    },
    body: companyName
})

首先:使用object代替new Headers(..):

fetch('www.example.net', {
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
    'X-My-Custom-Header': 'value-v',
    'Authorization': 'Bearer ' + token,
  }
});

其次:很高兴知道,headers 被 fetch 小写了!!

第三no-cors模式限制headers的使用到这个白名单:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type 其值为 ( application/x-www-form-urlencoded, multipart/form-data, text/plain )

这就是为什么只发送您的 Content-Type header 而不是 X-My-Custom-HeaderAuthorization

我也遇到了同样的问题。我通过从 javascript 中删除 'no-cors' 并在服务器端 spring boot 添加以下内容来解决它。

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity httpSecurity) throws Exception {
             .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

        }
    }