我正在尝试从HP Alm的REST API获取一些数据。它与一个小的curl脚本配合得很好——我得到了我的数据
现在,使用JavaScript、fetch和ES6(或多或少)这样做似乎是一个更大的问题。我一直收到以下错误消息:
无法加载获取API。对飞行前请求的响应不正确
通过访问控制检查:未显示“访问控制允许原点”标题
在请求的资源上显示。起源’http://127.0.0.1:3000”“是吗
因此不允许访问。响应的HTTP状态代码为501。
如果不透明响应满足您的需要,请将请求的模式设置为
“无cors”以获取禁用cors的资源
我理解这是因为我试图从本地主机中获取数据,解决方案应该使用CORS。现在我想我真的做到了,但不知怎么的,它要么忽略了我在标题中写的内容,要么问题出在其他地方
那么,是否存在实施问题?我做错了吗?很遗憾,我无法检查服务器日志。我真的有点困在这里了
函数performSignIn(){
let headers=新的headers();
headers.append('Content-Type','application/json');
headers.append('Accept','application/json');
headers.append('Access-Control-Allow-Origin','http://localhost:3000');
headers.append('Access-Control-Allow-Credentials','true');
headers.append('GET','POST','OPTIONS');
headers.append('Authorization','Basic'+base64.encode(username+“:“+password));
获取(登录){
//模式:“无cors”,
凭据:“包括”,
方法:“POST”,
标题:标题
})
.then(response=>;response.json())
.then(json=>;console.log(json))
.catch(错误=>;console.log('授权失败:'+错误消息));
}
我用的是铬。我也尝试过使用Chrome CORS插件,但随后我收到另一条错误消息:
响应中“Access Control Allow Origin”标头的值
当请求的凭据模式为时,不能为通配符“*”
“包括”。起源’http://127.0.0.1:3000因此,”不允许”
通道由发起的请求的凭据模式
XMLHttpRequest由withCredentials属性控制
这个答案涵盖了很多方面,因此分为三个部分:
- 如何使用CORS代理解决“无访问控制允许源站标头”问题
- 如何避免CORS飞行前
- 如何解决“访问控制允许源标题不能是通配符”的问题
如何使用CORS代理来避免“无访问控制允许源站标头”问题
如果您不控制前端代码向其发送请求的服务器,而该服务器的响应问题只是缺少必要的Access control Allow Origin
头,那么您仍然可以通过CORS代理发出请求来完成工作
您可以使用源代码轻松运行自己的代理https://github.com/Rob–W/cors-anywhere/.
您还可以使用5个命令,在2-3分钟内轻松地将自己的代理部署到Heroku:
git克隆https://github.com/Rob--W/cors-anywhere.git
cd-cors随处可见/
npm安装
赫罗库创造
git推送heroku主机
在运行这些命令之后,您将在运行自己的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
- 将
访问控制允许原点
标题添加到响应中 - 将带有添加的头的响应传递回请求的前端代码
然后浏览器允许前端代码访问响应,因为带有访问控制允许原点的响应是浏览器看到的
即使请求触发浏览器执行CORS飞行前选项
请求,这也会起作用,因为在这种情况下,代理还会发送飞行前成功所需的访问控制允许标头
和访问控制允许方法
标头
如何避免CORS飞行前检查
问题中的代码会触发CORS预飞行,因为它会发送授权
标题
https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
即使没有它,Content-Type:application/json
头也会触发预飞行
“飞行前”的意思是:在浏览器尝试问题代码中的POST
之前,它首先向服务器发送OPTIONS
请求,确定服务器是否选择接收具有授权
和内容类型的跨源
标题POST
:application/json
它与一个小的curl脚本配合得很好——我得到了我的数据
要使用curl
进行正确测试,必须模拟浏览器发送的飞行前选项
:
curl-i-X选项-H”;来源:http://127.0.0.1:3000" \
-H'访问控制请求方法:POST'\
-H'访问控制请求头:内容类型,授权'\
&引用;https://the.sign_in.url"
…带有https://the.sign_in.url
替换为您实际登录的URL
浏览器需要从该选项
请求得到的响应必须具有如下标题:
访问控制允许原点:http://127.0.0.1:3000
访问控制允许方法:POST
访问控制允许标头:内容类型、授权
如果选项
响应不包含这些标题,浏览器将立即停止,并且从不尝试发送POST
请求。此外,响应的HTTP状态代码必须是2xx,通常为200或204。如果是任何其他状态代码,浏览器将立即停止
问题中的服务器用501状态代码响应选项
请求,这显然意味着它试图表明它没有实现对选项
请求的支持。在这种情况下,其他服务器通常使用405“不允许使用方法”状态代码进行响应
因此,如果服务器以405或501或200或204以外的任何方式响应该选项
请求,或者如果服务器没有以这些必要的响应头响应,则您将永远无法从前端JavaScript代码直接向该服务器发出POST
请求
避免触发问题案例飞行前准备的方法是:
- 如果服务器不需要
授权
请求标头,而是依赖于POST
请求正文中嵌入的身份验证数据或作为查询参数 - 如果服务器不要求
POST
主体具有内容类型:application/json
媒体类型,而是将POST
主体接受为application/x-www-form-urlencoded
,并带有名为json
(或任何值为json数据的参数)
如何修复“访问控制允许源标题不能是通配符”问题
我收到另一条错误消息:
响应中“访问控制允许原点”标题的值
当请求的凭据模式为时,不能是通配符“*”
“包括”。来源“http://127.0.0.1:3000因此,不允许使用“
”
访问。由发起的请求的凭据模式
XMLHttpRequest由withCredentials属性控制。
对于具有凭据的请求,如果access Control Allow Origin
头的值为*
,浏览器将不允许前端JavaScript代码访问响应。相反,这种情况下的值必须与前端代码的来源完全匹配,http://127.0.0.1:3000
请参阅MDN HTTP访问控制(CORS)文章中的认证请求和通配符
如果您控制要向其发送请求的服务器,处理这种情况的一种常见方法是将服务器配置为获取Origin
请求头的值,并将其回送/反映到访问控制允许Origin
响应头的值中;e、 例如,使用nginx:
添加头访问控制允许源代码$http\u源代码
但这只是一个例子;其他(web)服务器系统也有类似的方法来回显原始值
我用的是铬。我也尝试过使用ChromeCors插件
Chrome CORS插件显然只是简单地将访问控制允许源代码:
头插入到浏览器看到的响应中。如果插件更智能,那么它将把伪Access Control Allow Origin
response头的值设置为前端JavaScript代码的实际来源,http://127.0.0.1:3000
因此,避免使用该插件,即使是用于测试。这只是分散注意力。要测试在没有浏览器过滤的情况下从服务器得到的响应,最好使用上面提到的curl-H
至于前端JavaScri