简体   繁体   English

通过浏览器请求时表达JS CORS

[英]Express JS CORS when requested via browser

While using an Express/NodeJS backend - I have a REST GETTER that is used to authenticate using strava (passport-strava) 使用Express / NodeJS后端时-我有一个REST GETTER,用于使用strava(passport-strava)进行身份验证

When I invoke the API URL directly( http://localhost:3000/api/auth/strava ) - the connection is successful and I'm able to retrieve the profile information. 当我直接调用API URL( http:// localhost:3000 / api / auth / strava )时-连接成功,并且能够检索配置文件信息。 However, when this is invoked through a browser widget, ie onClick of a HTML button and routed through to the backend - I'm thrown an error 但是,当通过浏览器小部件(即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.

I do understand that this is related to CORS and that the header "Access-Control-Allow-Origin" must be included however, there is no respite on adding this into the header with the appropriate value. 我确实知道这与CORS有关,并且必须包含标头“ Access-Control-Allow-Origin”,但是,使用适当的值将其添加到标头中并没有什么喘息的机会。

I tried to intercept the calls using chrome://net-internals to check if Access-Control-Allow-Origin is being stripped out and noticed the variations in calls - 我尝试使用chrome:// net-internals拦截呼叫,以检查是否剥离了Access-Control-Allow-Origin并注意到呼叫中的变化-

When called directly via the API - the calls are as follows 通过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

However, when routed via the widget the calls are as follows 但是,通过小部件路由时,调用如下

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

The difference that I seemed to pull out is the additional call 我似乎拉出的区别是额外的电话

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

which isn't made in the previous scenario. 这不是以前的情况。

These observations are made not only for the passport-strava package but the passport-facebook package as well. 这些观察结果不仅适用于stravel-strava包裹,还适用于passport-facebook包裹。 Therefore, I think there is something gravely incorrect that I'm doing to get into this state. 因此,我认为要进入这种状态需要做一些严重的错误。

Any assistance is well appreciated. 非常感谢您的协助。

Since you already know about CORS then I go into any details. 由于您已经了解CORS,因此我将详细介绍。

Basically your issue is with your REST server , it needs to set the response packet's header with the appropriate content so that the browser doesn't complain. 基本上,您的问题与REST server ,它需要使用适当的内容设置响应数据包的标头,以便浏览器不会抱怨。 Unfortunately this is a security feature. 不幸的是,这是一项安全功能。

So in your server code, you need to define a function that would do the above and set it as 1 of the middleware layer that express will have to parse when a HTTP comes through. 因此,在服务器代码中,您需要定义一个可以执行上述操作的函数,并将其设置为中间件层的1,当HTTP通过时,该中间件层必须解析。

Example : 范例

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);

Yes. 是。 As pointed out by 1 of the commenter the npm module cors can also do the job. 正如评论者中的1所指出的那样,npm模块cors也可以完成这项工作。

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

If you are intending to use it then you might be looking at this example usage: 如果您打算使用它,则可以查看以下示例用法:

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');
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM