如何在AngularJS资源中使用JSONP

Tom*_*ina 6 json angularjs

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

我收到意外的令牌错误,因为我不应该使用 $scope.news = JsonSource.feed();- 但我真的不知道我应该使用什么.我用Google搜索并搜索了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}
      });
  }]);
Run Code Online (Sandbox Code Playgroud)

控制器文件:

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

json文件(差不多; D)

{
   "title": "Tytu?",
   "link": "https:\/\/www.facebook.com\/",
   "entries": [
      {
         "title": " news 1",
         "id": "1"
      },
      {
         "title": " news 2",
         "id": "2"
     }
   ]
}
Run Code Online (Sandbox Code Playgroud)

编辑:

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

luk*_*paw 8

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

下面是一个做你想要的例子.请记住:

  • 包含一个文件 angular-resource.min.js
  • 注入ngResource服务模块
  • 注入motoAdsServices到app模块
  • 注入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>
Run Code Online (Sandbox Code Playgroud)

services.js

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

motoAdsServices.factory('Brand', ['$resource', function($resource) {
    return $resource('./brands.json', {}, {});
  }]);
Run Code Online (Sandbox Code Playgroud)

controllers.js

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

motoAdsApp.controller('AdvertsController', ['$scope', 'Brand', 
  function($scope, Brand) {

    $scope.brands = Brand.query();
}]);
Run Code Online (Sandbox Code Playgroud)

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"}]}
]
Run Code Online (Sandbox Code Playgroud)

Plunker的例子

更新 (因为应该是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 }
    });
  }]);
Run Code Online (Sandbox Code Playgroud)

和controllers.js

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

motoAdsApp.controller('AdvertsController', ['$scope', 'Brand', 
  function($scope, Brand) {

    $scope.brands = Brand.queryjsonp();
}]);
Run Code Online (Sandbox Code Playgroud)

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

有同样的问题: jasonp请求与角$资源 他发现服务器问题.

更新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'));
});
Run Code Online (Sandbox Code Playgroud)

路线/ 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));
  });
};
Run Code Online (Sandbox Code Playgroud)

更新3 (因为CORS应该添加到web-server.js(node.js)而不表示)

你有类似的东西: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);
    });
  }
};
Run Code Online (Sandbox Code Playgroud)

也许你有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'
      }
    });
  }
]);
Run Code Online (Sandbox Code Playgroud)

controllers.js

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

myApp.controller('MyController', ['$scope', 'FacebookFeed', 
  function($scope, FacebookFeed) {
    $scope.feeds = FacebookFeed.jsonp_query();
    console.log()
}]);
Run Code Online (Sandbox Code Playgroud)

的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>
Run Code Online (Sandbox Code Playgroud)

Plunker的例子


Tom*_*ina -3

对于那些(像我一样)认为如果某些东西在浏览器中工作它就应该在服务器脚本中工作的人来说,这是答案。

  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 流......叹息......