我正在运行一个React(16)Web应用程序(部署在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],
})
);
...其中FRONTEND_DOMAIN
是Heroku上环境配置变量中的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日):我已经能够在本地主机上复制这个问题,所以我编辑来表明这只是Safari中的一个问题。考虑到相关的问题和一些测试,我相信这与allowedHeaders
/ CORS Access-Control-Allow-Headers
配置有关,可能是Safari配置OPTIONS
预检请求的方式。我还不能看到所有请求的细节,甚至配置Reactotron和apisauce。
编辑(2020年6月7日):所以我注意到Safari中没有设置cookie,所以我在服务器端设置到express中的currentUser没有持久化(在req.session.currentUser中,我在登录后设置了它)。此外,虽然我能够在localhost中的某个位置产生错误,但我无法可靠地在本地复制它。
2条答案
按热度按时间bsxbgnwa1#
原来Safari屏蔽了我的API发送的cookie,这是因为Safari隐私设置中的“防止跨站点跟踪”选项。
因此,唯一的解决方法似乎是将API与Web应用程序放在同一个域中,或者使用代理,如本问答中所述:Is there a workaround for Safari iOS "Prevent Cross Site Tracking" option, when issuing cookies from API on different domain?
ua4mk5z42#
编辑:下面的答案只适用于
localhost
开发,不适用于远程服务器上也发生此问题的情况。这是开发模式下的临时解决方案。好吧,如果其他人发现这个问题,在Safari中有一个简单的解决方法。首先,确保你的开发菜单在菜单栏中,通过“Safari”-〉“设置”,并在“高级”选项卡中选择“在菜单栏中显示开发菜单”。一旦完成,你应该会看到开发菜单。现在,选择“开发”-〉“禁用跨源限制”。
Disable Cross-Origin Restrictions in Develop menu