带有 jsonp 的 AngularJS 资源服务失败

Posted

技术标签:

【中文标题】带有 jsonp 的 AngularJS 资源服务失败【英文标题】:AngularJS resource service with jsonp fails 【发布时间】:2012-11-04 00:53:23 【问题描述】:

我正在尝试在 AngularJS 中获取 rest api 的 JSON 输出。以下是我面临的问题:

Rest api url 中包含端口号,AngularJS 为变量插入该端口号。我为此尝试了几种解决方案,但都徒劳无功。 我在使用 JSONP 方法时遇到问题。 Rest api 未托管在同一域/服务器上,因此简单的 get 不起作用。 rest api 的参数是斜线分隔的,不像 html 查询字符串。其中一个参数是电子邮件地址,我认为“@”符号也会引起一些问题。我也无法解决这个问题。

我的 rest api 看起来像:http://myserver.com:8888/dosomething/me@mydomain.com/arg2。 示例代码/文档会很有帮助。

【问题讨论】:

【参考方案1】:

我在这个问题上遇到了很多困难,所以希望这对将来的人有所帮助:)

JSONP 需要一个函数回调,一个常见的错误是调用一个返回 JSON 的 URL,你会得到一个 Uncaught SyntaxError: Unexpected token : 错误。相反,JSONP 应该返回类似这样的内容(不要纠结于示例中的函数名称):

angular.callbacks._0("id":4,"name":"Joe")

documentation 告诉您在 URL 上传递 JSON_CALLBACK 是有原因的。这将被替换为回调函数名称来处理返回。每个 JSONP 请求都分配了一个回调函数,因此如果您执行多个请求,它们可能由 angular.callbacks._1、angular.callbacks._2 等处理。

考虑到这一点,您的请求应该是这样的:

var url = 'http://myserver.com:8888/dosomething/me@mydomain.com/arg2';
$http.jsonp(url + '?callback=JSON_CALLBACK')
   .then(function (response) 
       $scope.mydata = response.data;
       ...

那么AngularJS会实际请求(替换JSON_CALLBACK):

http://myserver.com:8888/dosomething/me@mydomain.com/arg2?callback=angular.callbacks._0

有些框架已经支持JSONP,但是如果你的api没有自动做,你可以从querystring中获取回调名来封装json。 示例在 Node.js 中:

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

app.get('/', function(req, res)
    // do something to get the json
    var json = '"id":4,"name":"Joe"';

    res.writeHead(200, "Content-Type": "application/javascript");
    res.write(req.query.callback + '(' + json + ')');
    res.end();
);
app.listen(8888);

【讨论】:

【参考方案2】:

我在这里遇到的主要问题与CORS 有关。通过禁用 Chrome 中的网络安全性,我获得了 $http 以从服务器检索 JSON 数据 - 在启动 Chrome 时使用 --disable-web-security 标志。

【讨论】:

【参考方案3】:

关于8888端口,看看是否可行:

$scope.url  = 'http://myserver.com:port/dosomething/:email/:arg2';
$scope.data = $resource($scope.url, port:":8888", email:'me@mydomain.com', 
                 arg2: '...', other defaults here, …)

【讨论】:

看看这些对 CORS 是否有帮助:***.com/questions/13007187/…,github.com/angular/angular.js/issues/934【参考方案4】:

尝试转义 ':' var url = 'http://myserver.com\:8888/dosomething/me@mydomain.com/arg2'; 很确定我在其他地方读到过这个

【讨论】:

: 字符在 JSON 中没有特殊含义。那不会有任何区别。 jsbin.com/xuvobi/1/edit?js,console

以上是关于带有 jsonp 的 AngularJS 资源服务失败的主要内容,如果未能解决你的问题,请参考以下文章

在 AngularJS 中为 $http 服务使用 JSONP 方法

AngularJS jsonp调用404状态

使用 AngularJS 从 NodeJS 服务器返回 JSONP

在 AngularJS 中设置 JSONP 回调函数

AngularJS 中的 JSONP 请求不像 jQuery 那样工作

带有服务器发送事件的 AngularJS