【问题标题】:how to use JSONP in AngularJS resource如何在 AngularJS 资源中使用 JSONP
【发布时间】:2013-11-30 07:12:14
【问题描述】:

我正在尝试将 json 对象导入变量。我根据教程使用服务。

我收到了意外的令牌错误,因为我不应该使用 $scope.news = JsonSource.feed(); - 但我真的不知道应该使用什么。我用谷歌搜索了 3 个小时,我发现只有 $http。或 $json。答案,但我觉得它可以做得更容易 - 更清晰。

(完美的解决方案是$scope.news = JsonSource.feed().entries ;D

服务文件:

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

AAAServices.factory('JsonSource', ['$resource',
  function($resource) {
    return $resource('https://www.facebook.com/feeds/page.php', {}, {
      feed: {method:'JSONP', {format: 'json', id:'459908', callback : JSON_CALLBACK}, isArray:false}
      });
  }]);

控制器文件:

var AAAControllers = angular.module('AAAControllers', [])
AAAControllers.controller('newsCtrl', ['$scope', 'JsonSource', 
  function newsCtrl($scope, JsonSource) {
     $scope.news = JsonSource.feed();
}]);

json 文件(几乎是 ;D)

{
   "title": "Tytuł",
   "link": "https:\/\/www.facebook.com\/",
   "entries": [
      {
         "title": " news 1",
         "id": "1"
      },
      {
         "title": " news 2",
         "id": "2"
     }
   ]
}

已编辑:

我将 $resource('file.json 更改为 https://www.facebook.com/feeds/page.php - 这样你就可以检查它是 json 还是 jsonp...

【问题讨论】:

    标签: json angularjs


    【解决方案1】:

    我没有注意到它需要成为 JSONP,所以我使用默认的 $resource 方法。

    下面是一个做你想做的事的例子。 请记住:

    • 包含一个文件angular-resource.min.js
    • ngResource 注入服务模块
    • motoAdsServices 注入应用模块
    • Brand 注入控制器
    • 其余的将做 Angular :)

    index.html

    <!DOCTYPE html>
    <html ng-app="motoAdsApp">
    
      <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.min.js"></script>
        <script type="text/javascript" src="controllers.js"></script>
        <script type="text/javascript" src="services.js"></script>
      </head>
    
      <body>
        <div ng-controller="AdvertsController">
          <label>Brand</label>
          <select name="brand" ng-model="brand" ng-options="b.name for b in brands">
            <option value=""></option>
          </select>
        </div>
      </body>
    
    </html>
    

    services.js

    var motoAdsServices = angular.module('motoAdsServices', ['ngResource']);
    
    motoAdsServices.factory('Brand', ['$resource', function($resource) {
        return $resource('./brands.json', {}, {});
      }]);
    

    controllers.js

    var motoAdsApp = angular.module('motoAdsApp', ['motoAdsServices']);
    
    motoAdsApp.controller('AdvertsController', ['$scope', 'Brand', 
      function($scope, Brand) {
    
        $scope.brands = Brand.query();
    }]);
    

    brands.json

    [
      {"name": "Audi", "models": [{"name": "A1"}, {"name": "A3"}, {"name": "A4"}]},
      {"name": "BMW", "models": [{"name": "Series 3"}, {"name": "Series 5"}, {"name": "Series 7"}]},
      {"name": "Citroen", "models": [{"name": "C1"}, {"name": "C2"}, {"name": "C3"}]},
      {"name": "Dacia", "models": [{"name": "Duster"}, {"name": "Logan"}, {"name": "Sandero"}]}
    ]
    

    Plunker example

    UPDATE (因为应该是 JSONP)

    要使用 JSONP,您应该只更改 services.js

    var motoAdsServices = angular.module('motoAdsServices', ['ngResource']);
    
    motoAdsServices.factory('Brand', ['$resource', function($resource) {
        return $resource('./brands.json', {}, {
             jsonpquery: { method: 'JSONP', params: {callback: 'JSON_CALLBACK'}, isArray: true }
        });
      }]);
    

    和controllers.js

    var motoAdsApp = angular.module('motoAdsApp', ['motoAdsServices']);
    
    motoAdsApp.controller('AdvertsController', ['$scope', 'Brand', 
      function($scope, Brand) {
    
        $scope.brands = Brand.queryjsonp();
    }]);
    

    它应该是工作。但服务器应该返回有效的 jsonp

    同样的问题: jsonp request with angular $resource 他发现服务器有问题

    UPDATE 2 (因为问题可能出在 node.js 服务器中的 CORS)

    server.js (node.js)

    var express = require('express');
    var path = require('path');
    var http = require('http');
    var brands = require('./routes/brands');
    var countries = require('./routes/countries');
    var adverts = require('./routes/adverts');
    
    var app = express();
    
    // ALLOW CORS!!!
    var allowCrossDomain = function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "X-Requested-With");
      next();
    };
    
    app.configure(function() {
      app.set('port', process.env.PORT || 3000);
      app.use(express.logger('dev'));  /* 'default', 'short', 'tiny', 'dev' */
      app.use(express.bodyParser()),
              app.use(allowCrossDomain);
      app.use(express.static(path.join(__dirname, 'public')));
    });
    
    app.get('/api/brands', brands.findAll);
    app.get('/api/countries', countries.findAll);
    app.get('/api/adverts', adverts.findAll);
    
    http.createServer(app).listen(app.get('port'), function() {
      console.log("Express server listening on port " + app.get('port'));
    });
    

    路线/brands.js

    exports.findAll = function(req, res) {
      var fs = require('fs');
      var file = './server/data/brands.json';
    
      fs.readFile(file, 'utf8', function(err, data) {
        if (err) {
          throw err;
        }
        res.send(JSON.parse(data));
      });
    };
    

    UPDATE 3 (因为 CORS 应该添加到 web-server.js (node.js) 中而不用 express)

    你有类似的东西: https://github.com/angular/angular-seed/blob/master/scripts/web-server.js

    所以你必须在响应头中添加 ALLOW CORS(看下面我添加了 2 行):

    StaticServlet.prototype.sendFile_ = function(req, res, path) {
      var self = this;
      var file = fs.createReadStream(path);
      res.writeHead(200, {
        'Content-Type': StaticServlet.
          MimeMap[path.split('.').pop()] || 'text/plain',
        // ALLOW CORS - line 1 !!!
        'Access-Control-Allow-Origin' : '*',
        // ALLOW CORS - line 2 !!!
        'Access-Control-Allow-Headers': 'X-Requested-With'
      });
      if (req.method === 'HEAD') {
        res.end();
      } else {
        file.on('data', res.write.bind(res));
        file.on('close', function() {
          res.end();
        });
        file.on('error', function(error) {
          self.sendError_(req, res, error);
        });
      }
    };
    

    也许你有 jsonp 的其他功能,所以也添加到res.writeHead(200, CORS 标头。

    更新 4 - ANGULARJS 通过 JSONP 调用 FACEBOOK

    这个解决方案应该可行!!!

    services.js

    var myServices = angular.module('myServices', ['ngResource']);
    
    myServices.factory('FacebookFeed', ['$resource',
      function($resource) {
        return $resource('https://graph.facebook.com/cocacola?callback=JSON_CALLBACK', {}, {
          jsonp_query: {
            method: 'JSONP'
          }
        });
      }
    ]);
    

    controllers.js

    var myApp = angular.module('myApp', ['myServices']);
    
    myApp.controller('MyController', ['$scope', 'FacebookFeed', 
      function($scope, FacebookFeed) {
        $scope.feeds = FacebookFeed.jsonp_query();
        console.log()
    }]);
    

    index.html

    <!DOCTYPE html>
    <html ng-app="myApp">
    
      <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.min.js"></script>
        <script type="text/javascript" src="controllers.js"></script>
        <script type="text/javascript" src="services.js"></script>
      </head>
    
      <body>
        <div ng-controller="MyController">
          <label>Facebook feeds</label></label>
          <pre>{{feeds}}</pre>
        </div>
      </body>
    
    </html>
    

    Plunker example

    【讨论】:

    • 不幸的是json在外部服务器上,所以出现Access-Control-Allow-Origin问题...我发现最好的解决方案是使用jsonp
    • 看看我的更新也许对你有帮助。当 Access-Control-Allow-Origin 问题出现时。您的服务器应该允许 CORS 请求。
    • 这正是我设置的 - 我发现没有区别。但是如何检查服务器是否返回有效的 jsonp?
    • 你的服务器允许 CORS 怎么样?例如,在 node.js 服务器中,您应该执行 res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); 以允许 CORS。所以也许问题不在于 Angular,而在于服务器。
    • 我刚刚在您的回答中查看了您更新的资源网址。我认为服务器 https://www.facebook.com/feeds/page.php 应该响应 CORS 标头。如果你打电话给https://www.facebook.com/feeds/page.php,为什么要使用 angular-seed web-script.js?
    【解决方案2】:

    对于那些认为(如我)认为如果某些东西在浏览器中工作它应该在服务器脚本中工作的人的答案。

    1. facebook 为墙的内容提供了非常漂亮的 json:

    https://www.facebook.com/feeds/page.php?format=json&id=xxxx

    1. 但您无法从 nodejs 获取它 - 因为跨域策略限制

    更多信息在这里:Loading facebook wall feed JSON issues

    所以,现在我必须为 facebook wall 搜索 jsonp 流...叹息....

    【讨论】:

      猜你喜欢
      • 2018-05-17
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多