我试图从惠普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属性控制。
如果你在macOS的开发环境中使用Node.js和Express.js作为后端,React和Axios作为前端,你需要在HTTPS下运行两边。以下是最终对我有效的方法(经过几个小时的深入研究和测试):
步骤1:创建SSL证书
只需按照如何在5分钟内让HTTPS在本地开发环境中工作的步骤进行操作。
你最终会得到几个文件作为凭据来运行HTTPS服务器和React web:
server.key & server.crt
您需要在前端和后端的根文件夹中复制它们(在生产环境中,您可能会考虑在后端的./ssh文件夹中复制它们)。
步骤2:后端设置
我读了很多建议使用“cors”包甚至设置(“Access-Control-Allow-Origin”,“*”)的回答,这就像在说:“欢迎黑客来我的网站”。就像这样做:
import express from 'express';
const emailRouter = require('./routes/email'); // in my case, I was sending an email through a form in React
const fs = require('fs');
const https = require('https');
const app = express();
const port = 8000;
// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('*', (req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://localhost:3000");
next();
});
// Routes definition
app.use('/email', emailRouter);
// HTTPS server
const credentials = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt')
};
const httpsServer = https.createServer(credentials, app);
httpsServer.listen(port, () => {
console.log(`Back-end running on port ${port}`);
});
如果你想测试https是否正确,你可以用下面的常量替换httpserver:
https.createServer(credentials, (req: any, res: any) => {
res.writeHead(200);
res.end("hello world from SSL\n");
}).listen(port, () => {
console.log(`HTTPS server listening on port ${port}...`);
});
然后从web浏览器https://localhost:8000/访问它
步骤3:前端设置
这是来自React前端的Axios请求:
await axios.get(`https://localhost:8000/email/send`, {
params: { /* Whatever data you want to send */ },
headers: {
'Content-Type': 'application/json',
}
})
现在,您需要使用我们已经创建的SSL凭据以HTTPS模式启动React web。在macOS终端中输入以下内容:
HTTPS=true SSL_CRT_FILE=server.crt SSL_KEY_FILE=server.key npm start
此时,您正在从前端端口3000的HTTPS连接发送请求,后端端口8000的HTTPS连接将接收该请求。CORS应该对此感到高兴;)