【问题标题】:Express JS CORS when requested via browser通过浏览器请求时表达 JS CORS
【发布时间】:2016-11-15 12:06:26
【问题描述】:

在使用 Express/NodeJS 后端时 - 我有一个 REST GETTER,用于使用 strava (passport-strava) 进行身份验证

当我直接调用 API URL (http://localhost:3000/api/auth/strava) - 连接成功并且我能够检索配置文件信息。 但是,当通过浏览器小部件调用它时,即 HTML 按钮的 onClick 并路由到后端 - 我被抛出一个错误

XMLHttpRequest cannot load https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

我明白这与 CORS 相关,并且必须包含标题“Access-Control-Allow-Origin”,但是将其添加到具有适当值的标题中没有任何喘息的机会。

我尝试使用 chrome://net-internals 拦截呼叫,以检查 Access-Control-Allow-Origin 是否被剥离并注意到呼叫的变化 -

直接通过API调用时——调用如下

1097271 URL_REQUEST http://localhost:3000/api/auth/strava
1097273 DISK_CACHE_ENTRY    http://localhost:3000/api/auth/strava
1097275 HTTP_STREAM_JOB https://www.strava.com/
1097276 CONNECT_JOB ssl/www.strava.com:443
1097277 CONNECT_JOB ssl/www.strava.com:443
1097278 SOCKET  ssl/www.strava.com:443
1097279 CONNECT_JOB ssl/www.strava.com:443
1097280 CONNECT_JOB ssl/www.strava.com:443
1097281 SOCKET  ssl/www.strava.com:443
1097282 DISK_CACHE_ENTRY    https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097283 HTTP_STREAM_JOB https://www.strava.com/
1097285 URL_REQUEST http://localhost:3000/api/auth/strava
1097288 DISK_CACHE_ENTRY    http://localhost:3000/api/auth/strava
1097290 HTTP_STREAM_JOB https://www.strava.com/
1097291 DISK_CACHE_ENTRY    https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097292 HTTP_STREAM_JOB https://www.strava.com/
1097293 DISK_CACHE_ENTRY    http://localhost:3000/api/auth/strava/callback?state=&code=7b5722c72f079ee2ac5dfeb7d5140cdc6375f5cc

但是,当通过小部件路由时,调用如下

1097337 URL_REQUEST http://localhost:3000/api/auth/strava
1097339 DISK_CACHE_ENTRY    http://localhost:3000/api/auth/strava
1097344 URL_REQUEST https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097346 DISK_CACHE_ENTRY    https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769
1097347 HTTP_STREAM_JOB https://www.strava.com/
1097348 CONNECT_JOB pm/ssl/www.strava.com:443
1097349 CONNECT_JOB pm/ssl/www.strava.com:443
1097350 HOST_RESOLVER_IMPL_JOB  www.strava.com
1097352 SOCKET  pm/ssl/www.strava.com:443
1097353 CONNECT_JOB pm/ssl/www.strava.com:443
1097354 SOCKET  pm/ssl/www.strava.com:443

我似乎拔出的区别是额外的电话

1097344 URL_REQUEST https://www.strava.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fstrava%2Fcallback&client_id=9769

前一个场景中没有。

这些观察不仅适用于 passport-strava 包,也适用于 passport-facebook 包。因此,我认为为了进入这种状态,我正在做一些非常不正确的事情。

非常感谢任何帮助。

【问题讨论】:

  • 您可以使用此插件在您的服务器上启用 cors 标头。 CORS plugin
  • 谢谢,我试过了 - 但设置原点也没有帮助。

标签: javascript node.js express cors passport-facebook


【解决方案1】:

既然您已经了解 CORS,那么我将详细介绍。

基本上你的问题是你的REST server,它需要用适当的内容设置响应包的头部,这样浏览器就不会抱怨。不幸的是,这是一项安全功能。

因此,在您的服务器代码中,您需要定义一个执行上述操作的函数,并将其设置为中间件层之一,当 HTTP 通过时,express 必须对其进行解析。

示例

var express = require('express');
var app = express();

var httpAccessControlPolicy = function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key,Authorization');
  res.setHeader('Access-Control-Allow-Credentials', false);

  next();
};

app.use(httpAccessControlPolicy);

是的。正如一位评论者所指出的,npm 模块cors 也可以完成这项工作。

CORShttps://www.npmjs.com/package/cors

如果您打算使用它,那么您可能正在查看此示例用法:

var express = require('express')
  , cors = require('cors')
  , app = express();

app.use(cors());

app.get('/products/:id', function(req, res, next){
  res.json({msg: 'This is CORS-enabled for all origins!'});
});

app.listen(80, function(){
  console.log('CORS-enabled web server listening on port 80');
});

【讨论】:

  • 这可能是我做的第一件事。但是,在其中一种情况下,我仍然会感到头晕目眩,那就是当 API 被间接请求(调用)时,比如通过 UI 按钮或另一个休息重定向。我同意我的 REST 服务器存在问题,但我不知道如何找出答案。
  • 你在这里做一些oauth2认证吗?听起来外部服务正在指示您的浏览器调用您的端点的 1,并且由于响应标头缺少 CORS 信息,它无法读取响应。因此浏览器阻止了它。
  • 感谢您的建议,@samuel。我没有做任何不同的事情 - 我将尝试 the facebook passport github example 上列出的示例并从那里跟踪它
  • 你是对的 - 有东西取消了发送的请求。顺便说一句,当呼叫不起作用时,这是我在 chrome://net-internal t=46517 [st=16] DELEGATE_INFO [dt=1] --> delegate_info = "AsyncResourceHandler" t=46518 [st=17] -URL_REQUEST_DELEGATE t=46518 [st=17] CANCELLED 上看到的,我无法确定是什么取消了请求!
猜你喜欢
  • 2015-03-09
  • 2012-12-22
  • 2017-05-07
  • 1970-01-01
  • 2017-05-14
  • 2014-10-07
  • 2011-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多