我试图从惠普Alm的REST API中获取一些数据。它使用一个小的curl脚本工作得很好——我得到了我的数据。
现在用JavaScript、fetch和ES6(或多或少)来实现这一点似乎是一个更大的问题。我一直收到这个错误信息:
无法加载获取API。对飞行前请求的响应则不然
pass访问控制检查:没有' access - control - allow - origin '头
显示在所请求的资源上。“http://127.0.0.1:3000”是
因此不允许访问。响应的HTTP状态代码为501。
如果不透明响应满足您的需求,请将请求的模式设置为
'no-cors'获取禁用CORS的资源。
我明白这是因为我试图从我的本地主机内获取数据,解决方案应该使用跨起源资源共享(CORS)。我认为我确实这样做了,但不知为何,它要么忽略了我在头文件中写的内容,要么是其他问题。
那么,是否存在执行问题?我做错了吗?很遗憾,我无法查看服务器日志。我真的有点卡在这里了。
function performSignIn() {
let headers = new 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));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
我正在使用Chrome浏览器。我也尝试使用Chrome CORS插件,但随后我得到另一个错误消息:
响应中的'Access-Control-Allow-Origin'报头的值
当请求的凭据模式为时,一定不能是通配符'*'
“包括”。因此,来源“http://127.0.0.1:3000”是不允许的
访问。对象发起的请求的凭据模式
XMLHttpRequest由withCredentials属性控制。
在我的react/express应用程序中遇到了这个问题。在server.js(或你的服务器文件名)中添加以下代码为我解决了这个问题。安装cors然后
const cors = require('cors');
app.use(cors({
origin: 'http://example.com', // use your actual domain name (or localhost), using * is not recommended
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Origin', 'X-Requested-With', 'Accept', 'x-client-key', 'x-client-token', 'x-client-secret', 'Authorization'],
credentials: true
}))
现在,您可以从前端直接调用API,而无需传递任何额外参数。
出现问题是因为你在前端添加了以下代码作为请求头:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
这些头属于响应,而不是请求。所以去掉它们,包括这一行:
headers.append('GET', 'POST', 'OPTIONS');
你的请求有“Content-Type: application/json”,因此触发了所谓的CORS preflight。这导致浏览器使用OPTIONS方法发送请求。详细信息请参见CORS飞行前准备。
因此,在你的后端,你必须通过返回响应头来处理这个预飞行的请求,其中包括:
Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept
当然,实际的语法取决于后端使用的编程语言。
在你的前端,它应该像这样:
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
headers.append('Origin','http://localhost:3000');
fetch(sign_in, {
mode: 'cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed: ' + error.message));
}