我有一个使用
webpack-simple
选项生成的 Vue 应用程序。我正在尝试向 GET
发出 https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en
请求,但收到错误:
XMLHttpRequest 无法加载
。 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点 'https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en
' 访问。http://127.0.0.1:8080
我正在使用 vue-resource 并添加了:
Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'
没有任何效果。
我还在
devServer
中的webpack.config.js
选项中添加了这个:
devServer: {
historyApiFallback: true,
noInfo: true,
headers: {
"Access-Control-Allow-Origin": "*"
}
}
这也不能解决问题;错误消息保持不变。
如何解决这个问题?
Access-Control-Allow-Origin
是响应服务器必须发送的 response 标头。
所有其他
Access-Control-Allow-*
标头都是服务器发送的响应标头。
如果您不控制请求发送到的服务器,并且响应的问题只是缺少
Access-Control-Allow-Origin
标头或其他 Access-Control-Allow-*
标头,您仍然可以通过发出请求来使事情正常工作CORS 代理。
您可以使用 https://github.com/Rob--W/cors-anywhere/ 中的代码轻松运行自己的代理。
您还可以使用 5 个命令,在 2-3 分钟内轻松将自己的代理部署到 Heroku:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
运行这些命令后,您最终会得到自己的 CORS Anywhere 服务器,例如,
https://cryptic-headland-94862.herokuapp.com/
。
现在,在您的请求 URL 前加上代理的 URL:
https://cryptic-headland-94862.herokuapp.com/https://example.com
添加代理 URL 作为前缀会导致请求通过您的代理发出,这:
https://example.com
。https://example.com
的回复。Access-Control-Allow-Origin
标头添加到响应中。浏览器然后允许前端代码访问响应,因为浏览器看到的是带有
Access-Control-Allow-Origin
响应头的响应。
即使请求是触发浏览器执行 CORS 预检
OPTIONS
请求的请求,此方法也有效,因为在这种情况下,代理还会发回预检成功所需的 Access-Control-Allow-Headers
和 Access-Control-Allow-Methods
标头。
如果您的前端代码将
Access-Control-Allow-Origin
标头或其他 Access-Control-Allow-*
标头添加到请求中,请删除该代码 - 因为添加这些请求标头的唯一效果是,您将触发浏览器发送 CORS 预检 OPTIONS
请求,而不是代码中实际的 GET
或 POST
请求。
要在本地系统上运行网络应用程序,您可以通过添加 --disable-web-security 标志来禁用 Chrome 安全功能。
我在 Windows 上使用以下命令来解决 XMLHttpError:
cd C:\Program Files\Google\Chrome\Application & chrome.exe "http://localhost:8000/" --user-data-dir="C:\new" --disable-web-security
cd C:\flutter\MyProject\build\web & python -m http.server 8000
好吧,这个答案与问题并不真正相关,但对于那些无法接触API服务器端、免费使用来自Rob的代理服务的人来说可能很有用--W
function doCORSRequest(appUrl) {
const cors_api_url = 'https://cors-anywhere.herokuapp.com/';
let nUrl = cors_api_url + appUrl;
fetch(nUrl)
.then(response => {
if(response.status !== 200) {
alert("Error :( try later.")
return;
}
response.json()
.then(data => showResult(data))
})
}
doCORSRequest(yourURL);