自定义配置导致的奇怪 CORS 问题

Posted

技术标签:

【中文标题】自定义配置导致的奇怪 CORS 问题【英文标题】:weird CORS problem caused by custom config for fetch 【发布时间】:2021-07-01 19:30:33 【问题描述】:

我正在为 javascript 中的 fetch 方法编写一个小包装器(我非常了解像 Axios 这样的库可以做同样的事情)。我的想法来自a blog post

我的代码是这样的

async function apiCall(
  endpoint,
   data, headers: customHeaders, ...customConfig  = 
) 
  console.log("endpoint", endpoint);
  const config = 
    method: data ? "POST" : "GET",
    body: data ? JSON.stringify(data) : undefined,
    headers: 
      "content-type": data ? "application/json" : undefined,
      ...customHeaders
    ,
    ...customConfig
  ;

  return window.fetch(endpoint, config).then(async (response) => 
    if (response.ok) 
      return response.json();
     else 
      // By default, window.fetch will only reject a promise if the actual request itself failed (network error), not if it returned a "Client error response".
      const error = await response
        .json()
        .catch(() => new Error("invalid json"));
      return Promise.reject(error);
    
  );


export function requestMovies(query) 
  const endpoint = `$apiULR?apikey=$API_KEY&s=$encodeURIComponent(query)`;

  return apiCall(endpoint);


但是,我遇到了TypeError Failed to fetch,我认为这是由 CORS 引起的。

如果我从window.fetch 中取出config,如

async function apiCall(
  endpoint,
   data, headers: customHeaders, ...customConfig  = 
) 
  return window.fetch(endpoint).then(async (response) => 
    if (response.ok) 
      return response.json();
     else 
      // By default, window.fetch will only reject a promise if the actual request itself failed (network error), not if it returned a "Client error response".
      const error = await response
        .json()
        .catch(() => new Error("invalid json"));
      return Promise.reject(error);
    
  );

问题就解决了。不确定究竟是哪一部分触发了这个 CORS 问题...

这是一个现场演示:https://codesandbox.io/s/charming-saha-4c2bh?file=/src/index.js

【问题讨论】:

这是意料之中的,因为对于headers: "content-type": data ? "application/json" : undefined, ...customHeaders ,问题中显示的代码会导致将content-type 请求标头添加到请求中——这会导致浏览器记录错误“访问从源 'https://4c2bh.csb.app' 在 'https://www.omdbapi.com/?apikey=[apikey]&s=war' 获取已被 CORS 策略阻止:在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段内容类型。”。所以https://www.omdbapi.com/?apikey 不允许带有内容类型标头的请求 【参考方案1】:

按照data未给出路径:

    三元进入false case headers 得到一个条目 content-type: undefined 请求添加了此标头 请求被 api 拒绝,因为它包含一个内容类型的标头(可能带有字符串'undefined'

解决方案:此处不要使用三元组,将其替换为if,以摆脱undefined 条目。 另外:阅读 javascript 对象中 null、未定义值和“拥有自己的属性”之间的差异

【讨论】:

我知道三元是如何工作的,并且我知道 content-type: undefined 是作为结果添加的。我不明白为什么content-type: undefined 导致了cors 问题。 因为它显然在错误消息中这么说?引用您的评论:“已被 CORS 政策阻止:在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段内容类型”

以上是关于自定义配置导致的奇怪 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

具有自定义授权者和 CORS 间歇性 200 然后 403 然后 200 的 AWS API 网关 ...奇怪

如何为 AWS API Gateway 自定义授权方配置 CORS?

具有自定义样式的 TextView 导致奇怪的膨胀异常

sort/stable_sort 自定义比较功能导致一些奇怪的问题

将 UISearchBar 放在自定义 UITableview 中会导致奇怪的动画

自定义 UITabBarItem 的文本颜色和字体导致 swift 出现奇怪的结果