【问题标题】:CORS blocks one API request (not others) in SafariCORS 在 Safari 中阻止一个 API 请求(而不是其他请求)
【发布时间】:2020-09-22 01:17:57
【问题描述】:

我正在运行一个 React (16) webapp(部署在 Netlify 上),如果它的 API 调用被 CORS 阻止但仅在 Safari 中,它会失败。在 Chrome 或 Firefox 中没有问题。控制台显示如下:

Origin https://chicha.netlify.app is not allowed by Access-Control-Allow-Origin.
XMLHttpRequest cannot load https://chicha-api.herokuapp.com/votes due to access control checks.
Failed to load resource: Origin https://chicha.netlify.app is not allowed by Access-Control-Allow-Origin.

被阻止请求的标头(Safari):

Summary
URL: https://chicha-api.herokuapp.com/votes
Status: —
Source: —
Initiator: 
xhr.js:178


Request
Accept: application/json, text/plain, */*
Origin: https://chicha.netlify.app
Referer: https://chicha.netlify.app/events
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
X-Requested-With: XMLHttpRequest

Response
No response headers

以下是未被阻止的同一请求的标头 (Chrome):

Request URL: https://chicha-api.herokuapp.com/votes
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: 52.214.138.78:443
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: x-requested-with
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: https://chicha.netlify.app
Connection: keep-alive
Content-Length: 0
Date: Wed, 03 Jun 2020 10:43:59 GMT
Server: Cowboy
Vary: Origin, Access-Control-Request-Headers
Via: 1.1 vegur
X-Powered-By: Express
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,es;q=0.9,ca;q=0.8,fr;q=0.7
Access-Control-Request-Headers: x-requested-with
Access-Control-Request-Method: GET
Connection: keep-alive
Host: chicha-api.herokuapp.com
Origin: https://chicha.netlify.app
Referer: https://chicha.netlify.app/events
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36

应用使用 axios 进行调用,配置如下:

class ApiClient {
  constructor() {
    this.apiClient = axios.create({
      baseURL: process.env.REACT_APP_BACKEND_URI,
      withCredentials: true,
      headers: { 'X-Requested-With': 'XMLHttpRequest' },
    });
  }

  getVotes = () => this.apiClient.get('/votes');
  getEvents = () => this.apiClient.get('/events');
...

API(在 Heroku 上部署 Express 的 Node.js)具有以下 CORS 配置:

app.use(
    cors({
        credentials: true,
        origin: [process.env.FRONTEND_DOMAIN],
    })
);

...在 Heroku 上的环境配置变量中,FRONTEND_DOMAINhttps://chicha.netlify.app

奇怪的是其他 API 请求都没有问题。成功请求的 API 标头(Safari):

Summary
URL: https://chicha-api.herokuapp.com/events
Status: 304 Not Modified
Source: Memory Cache
Address: 52.215.119.172:443
Initiator: 
xhr.js:178

Request
GET /events HTTP/1.1
Accept: application/json, text/plain, */*
Origin: https://chicha.netlify.app
Accept-Language: en-gb
If-None-Match: W/"c010-APRvUYTowK2az7ovB1dPcY+SGuk"
Host: chicha-api.herokuapp.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
Referer: https://chicha.netlify.app/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
X-Requested-With: XMLHttpRequest

Response
HTTP/1.1 304 Not Modified
Connection: keep-alive
Access-Control-Allow-Credentials: true
ETag: W/"c010-APRvUYTowK2az7ovB1dPcY+SGuk"
Date: Wed, 03 Jun 2020 10:26:18 GMT
Via: 1.1 vegur
Access-Control-Allow-Origin: https://chicha.netlify.app
Content-Length: 0
Vary: Origin
Server: Cowboy
X-Powered-By: Express

被阻止的请求有一个与来源不同的引用者这一事实是否重要?或者可能是 cookie 没有随请求一起发送的问题(尽管 axios 中有 withCredentials 配置)?

编辑(2020 年 6 月 4 日):我已经能够在 localhost 上复制它,所以我正在编辑以表明这只是 Safari 中的一个问题。鉴于相关问题和一些测试,我认为这与allowedHeaders / CORS Access-Control-Allow-Headers 配置有关,也可能与Safari 配置OPTIONS 预检请求的方式有关。即使配置 Reactotron 和 apisauce,我也无法查看所有请求详细信息。

编辑(2020 年 6 月 7 日):所以我注意到 Safari 中没有设置 cookie,所以我在服务器端设置为 express 的 currentUser 没有持久化(在我之后设置的 req.session.currentUser 中登录)。此外,虽然我能够在 localhost 中的某个时间点产生错误,但我无法在本地可靠地复制它。

【问题讨论】:

    标签: node.js safari axios cors access-control


    【解决方案1】:

    事实证明,由于 Safari 隐私设置中的“防止跨站点跟踪”选项,Safari 阻止了从我的 API 发送的 cookie。禁用此功能,一切正常。

    因此,似乎唯一的解决方法是将 API 与 Web 应用程序放在同一个域中,或者使用代理,如此问题和答案中所引用: Is there a workaround for Safari iOS "Prevent Cross Site Tracking" option, when issuing cookies from API on different domain?

    【讨论】:

      猜你喜欢
      • 2016-04-06
      • 2020-08-16
      • 2015-09-11
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 2018-10-18
      • 2022-11-01
      • 1970-01-01
      相关资源
      最近更新 更多