node.js - Node Express Cors 问题
问题描述
我不明白为什么 cors express 中间件不起作用。cors、express 和 ejs 都保存在 package.json 中。如果我在前端添加 corsanywhere 代理,该应用程序可以正常工作,但我喜欢在服务器端解决这个问题。非常感谢任何帮助我一直坚持这一点。
api 位于获取视图/索引路径中
错误是: CORS 策略已阻止从源“ http://localhost:3000 ”获取“ https://api.darksky.net/forecast/ ”的访问权限:没有“Access-Control-Allow-Origin”请求的资源上存在标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
const express = require('express');
const app = express();
const ejs = require('ejs');
const cors = require('cors');
const PORT = process.env.PORT || 3000;
// app.use((req, res, next) => {
// res.header('Access-Control-Allow-Origin', '*')
// res.header('Access-Control-Allow-Headers', 'Origin', 'X-Requested-With')
// next();
// });
app.use(cors());
app.use(express.static(__dirname + '/Public'));
app.set('view engine', 'ejs');
app.get('/', cors(), (req, res) => {
res.render(__dirname + '/Views/index')
});
app.listen(PORT, () => {
console.log(`server is listening on ${PORT}`)
});
客户端:
它与那里的 ${proxy} 一起工作,但我想摆脱它
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(position => {
long = position.coords.longitude;
lat = position.coords.latitude;
var proxy = 'https://cors-anywhere.herokuapp.com/'
var api = `${proxy}https://api.darksky.net/forecast/042750f3abefefdfe2c9d43cf33ce576/${lat},${long}`;
fetch(api)
.then(response => {
return response.json();
})
.then(data => {
let {temperature, summary, icon,} = data.currently;
temperatureDegree.textContent = Math.floor(temperature);
temperatureDescription.textContent = summary;
locationTimezone.textContent = data.timezone;
setIcons(icon, document.querySelector('.icon'
w
``````
解决方案
因此,如果您尝试https://api.darksky.net/forecast/
从您的网页访问某些其他服务(您无法控制),那么您无法做任何事情来让 COR 为之工作。由api.darksky.net
服务器决定是否允许使用 COR。你无法改变这一点。
您可以从您的网页向您的服务器发出请求,要求它为api.darksky.net
您获取一些数据,然后将其返回到您的网页(作为一个简单的代理)。您的服务器在访问时不受任何 COR 限制api.darksky.net
。只有浏览器受 COR 限制。
而且,正如您所发现的,您还可以使用启用 COR 并为您获取数据的代理服务。
假设您要代理 darksky API 的部分,您可以执行以下简单操作:
const express = require('express');
const app = express();
const request = require('request');
const apiRouter = express.Router();
// maps /api/forecast/whatever to http://api.darksky.net/forecast/developerKey/whatever
// and pipes the response back
const apiKey = "yourAPIKeyHere";
apiRouter.get("/*", (req, res, next) => {
// parse out action and params
// from an incoming URL of /api/forecast/42.3601,-71.0589
// the /api will be the root of the router (so not in the URL here)
// "forecast" will be the action
// "42.3601,-71.0589" will be the params
let parts = req.path.slice(1).split("/"); // split into path segments, skipping leading /
let action = parts[0]; // take first path segment as the action
let params = parts.slice(1).join("/"); // take everything else for params
request({
uri: `https://api.darksky.net/${action}/${apiKey}/${params}`,
method: "get"
}).pipe(res);
});
app.use("/api", apiRouter);
app.listen(80);
现在,当您发送此服务器时,此请求:
/api/forecast/42.3601,-71.0589
它将要求:
https://api.darksky.net/forecast/yourAPIKeyHere/42.3601,-71.0589
并将结果通过管道传回给调用者。我运行了这个测试应用程序,它对我有用。虽然我在 darksky.net API 中除了预测 URL 之外没有看到任何其他内容,但它适用于任何格式的/api/someAction/someParams
.
请注意,您可能不想在您的服务器上启用 CORS,因为您不希望其他人的网页能够使用您的代理。而且,由于您现在只是向自己的服务器发送请求,因此您不需要 CORS 就可以做到这一点。
推荐阅读
- c# - 过滤 WPF 虚拟化 TreeView 的高效方法
- twitter-bootstrap - 是否可以将 jsf 与引导程序一起使用
- java - DynamoDB,使用偏移量/限制对 100,000 个文档进行分页的方法?
- java - OpenCV 和 Java,读取图像
- python - os.startfile 错误:FileNotFoundError: [WinError 2] 系统找不到指定的文件:
- elasticsearch - 使用 JAVA 中的日期数学表达式删除弹性搜索上超过 30 天的基于时间的索引会给出 indexNotExists 异常
- javascript - 带有参数的查询不起作用的 Firestore
- javascript - 查询字符串起飞最后一个 ')' 在 url
- neo4j - 如果 2 个节点之间有一个节点,则 Neo4J 深度
- javascript - Ajax 请求 laravel 上传表单有时效果很好,但有时会继续加载