简体   繁体   English

将授权数据通过POST或GET请求的头部从Angular传递到NodeJS服务器

[英]Passing authorization data through headers of POST or GET request from Angular to a NodeJS server

On the one hand I have Angular running locally though port 9000 using gulp watch 一方面,我使用gulp watch通过端口9000在本地运行Angular

And on the other I have a nodejs server running on port 3000. 另一方面,我有一个在端口3000上运行的nodejs服务器。

Within Angular I am using the following code to POST/GET. 在Angular中我使用以下代码进行POST / GET。

$scope.click = function(){
  console.log("clicked");

  var req = {
     method: 'POST',
     url: 'http://localhost:3000/hello?ids=1,2,3',
     // headers: {
       // 'Content-Type': 'text/plain'
       // ,'Authorization' : 'Basicbulletproof'
     // },
     data: {
      something: "some_data"
     }
    };
    success( function( data, status, headers, config ) {
      // something called here
      console.log( "SUCCESS! With data: ", data );
      console.log( "And status: ", status );
    }).
    error( function( data, status, headers, config ) {
      // something called here
      console.log( "ERROR! With data: ", data );
      console.log( "And status: ", status );   
    });
};

And on my node server I have: 在我的节点服务器上,我有:

app.all( '/*', function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type' );
  next();
});

app.post('/hello', function ( req, res ) {
  console.log( "HEADER: ", req.headers );
  console.log( "QUERY: ", req.query );
  console.log( "BODY: ", req.body );

  var metrics = {someData: "to send back to Angular"};
  res.send(metrics);

} );

When the click function is ran through Angular, on the NodeJS side I get the following: 当单击函数通过Angular运行时,在NodeJS端我得到以下内容:

OPTIONS /hello?ids=1,2,3 200 15.265 ms - 13
HEADER:  { host: 'localhost:3000',
  connection: 'keep-alive',
  'content-length': '49',
  accept: 'application/json, text/plain, */*',
  origin: 'http://localhost:9000',
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36',
  'content-type': 'application/json;charset=UTF-8',
  referer: 'http://localhost:9000/',
  'accept-encoding': 'gzip, deflate',
  'accept-language': 'en-US,en;q=0.8' }
QUERY:  { ids: '1,2,3' }
BODY:  { something: 'some_data' }
POST /hello?ids=1,2,3 200 6.073 ms - 22

And on the Angular browser page I get: 在Angular浏览器页面上,我得到:

clicked
SUCCESS! With data: Object {someData: "to send back to Angular"}
And status: 200

Which is all nice, but as soon as I try to alter the header by adding more elements to it from Angular it all goes Pete Tong... 这一切都很好,但是当我尝试通过从Angular添加更多元素来改变标题时,所有这些都是Pete Tong ...

Therefore what modifications do I need to include in order for me to pass authorization info like tokens from Angular to NodeJS on both sides to allow those to go through successfully? 因此,我需要进行哪些修改才能将授权信息(如Angular中的令牌)传递给NodeJS,以便成功通过?

Thank you for the help. 感谢您的帮助。

@Jules for angular @Jules for angular

 $scope.click=function(){

  $http.post("http://localhost:3000/hello"+ids+"").success(function(data){    
//console.log(data);
    $scope.load=angular.fromJson(data);

  }).error(function(){alert("Error");
            });
}

and node server 和节点服务器

app.all( '/*', function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type' );
  next();
});

app.post('/hello/:ids', function ( req, res ) {
  //console.log( "HEADER: ", req.headers );
  console.log( "QUERY: ", req.param.ids );
//  console.log( "BODY: ", req.body );

  var metrics = {someData: "to send back to Angular"};
  res.send(metrics);

} );

First, your success() handler just returns the data, but that's not returned to the caller of getData() since it's already in a callback. 首先,你的success()处理程序只返回数据,但是它没有返回给getData()的调用者,因为它已经在回调中了。 $http is an asynchronous call that returns a $promise, so you have to register a callback for when the data is available. $ http是一个返回$ promise的异步调用,因此您必须在数据可用时注册回调。

I'd recommend looking up Promises and the $q library in AngularJS since they're the best way to pass around asynchronous calls between services. 我建议在AngularJS中查找Promises和$ q库,因为它们是传递服务之间异步调用的最佳方式。

For simplicity, here's your same code re-written with a function callback provided by the calling controller: 为简单起见,这里是使用调用控制器提供的函数回调重写的相同代码:

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function(callbackFunc) {
    $http({
        method: 'GET',
        url: 'https://www.example.com/api/v1/page',
        params: 'limit=10, sort_by=created:desc',
        headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
     }).success(function(data){
        // With the data succesfully returned, call our callback
        callbackFunc(data);
    }).error(function(){
        alert("error");
    });
 }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData(function(dataResponse) {
        $scope.data = dataResponse;
    });
});

Now, $ http actually already returns a $promise, so this can be re-written: 现在,$ http实际上已经返回$ promise,所以这可以重写:

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
    // $http() returns a $promise that we can add handlers with .then()
    return $http({
        method: 'GET',
        url: 'https://www.example.com/api/v1/page',
        params: 'limit=10, sort_by=created:desc',
        headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
     });
 }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData().then(function(dataResponse) {
        $scope.data = dataResponse;
    });
});

Finally, there's better ways to configure the $ http service to handle the headers for you using config () to setup the $ httpProvider . 最后,有更好的方法来配置$ http服务来使用config ()来设置$ httpProvider来处理标头。 Checkout the $ http documentation for examples. 查看$ http文档以获取示例。

$scope.click = function(){
  console.log("clicked");

   var req = {
     method: 'POST',
     url: 'http://localhost:3000/hello?ids=1,2,3',
     headers: {
      'Authorization' : 'Basicbulletproof'
     },
     data: {
       something: "some_data"
     }
   };
   success( function( data, status, headers, config ) {
     // something called here
     console.log( "SUCCESS! With data: ", data );
     console.log( "And status: ", status );
   }).
   error( function( data, status, headers, config ) {
     // something called here
     console.log( "ERROR! With data: ", data );
     console.log( "And status: ", status );   
   });
 };

And on my node server I have: 在我的节点服务器上,我有:

 app.all( '/*', function(req, res, next) {
   res.setHeader('Access-Control-Allow-Origin', '*');
   res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization' );
   next();
 });

 app.post('/hello', function ( req, res ) {
   console.log( "HEADER: ", req.headers );
   console.log( "QUERY: ", req.query );
   console.log( "BODY: ", req.body );

   var metrics = {someData: "to send back to Angular"};
   res.send(metrics);

 });

As you can see I was missing the "Authorization" on the node serve as part of the res.setHeader('Access-Control-Allow-Headers',... 正如您所看到的,我错过了节点上的“授权”作为res.setHeader的一部分('Access-Control-Allow-Headers',...

And then on Angular side just setting the Header with the Authorization passes the information across to Nodejs successfully. 然后在Angular方面,只需使用Authorization设置Header就可以成功地将信息传递给Nodejs。

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

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