首页 > 解决方案 > 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

``````

标签: node.jsexpresscors

解决方案


因此,如果您尝试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 就可以做到这一点。


推荐阅读