【发布时间】: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_DOMAIN 是 https://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