如何在 AngularJS 中插入命令或阻止 $http 的 JSONP 自动解析?
Posted
技术标签:
【中文标题】如何在 AngularJS 中插入命令或阻止 $http 的 JSONP 自动解析?【英文标题】:How can I insert commands before or prevent $http's JSONP automatic parsing in AngularJS? 【发布时间】:2013-06-24 08:25:10 【问题描述】:我发现的关于 $http 或 angularjs 的几乎所有问题或解释通常都假设您可以修改请求的响应。我不能这样做,而且我得到的响应格式不正确(根据 AngularJS 解析器)。它以一致的方式格式错误,因此我可以在解析之前修改纯文本以解决问题,但是响应拦截器和转换响应函数都会在默认(基于内容类型?)解析之后发生。
编辑:问题在于我需要使用 JSONP 方法从另一个站点请求信息,但数据没有预期的 JSONP 回调所以某些东西(我'我仍然不确定它是基于内容还是 AngularJS 代码的浏览器)引发语法错误。
新问题:有人知道解决这个问题的方法吗?
【问题讨论】:
到目前为止,没有人能够回答关于在处理之前解析 JSONP 响应的开放性问题。 【参考方案1】:Angular 在 1.5.8 版本中添加了 $jsonpCallbacks https://github.com/angular/angular.js/blob/master/src/ng/jsonpCallbacks.js
这允许您修改回调函数。
【讨论】:
【参考方案2】:这已经过测试并且确实有效。如果您还有其他问题,请告诉我。 http://jsfiddle.net/moderndegree/Kn3Tc/
HTML
<div ng-app="myApp">
<div ng-controller="myController">
results.tada
</div>
</div>
Javascript
angular.module('myApp', ['ngResource']).
factory('myService', function($http, $resource, $log)
return $resource('/', ,
get:
method: 'GET',
// placed custom transform ahead of $http default
transformRequest: [function(data, headersGetter)
$log.info(data);
$log.info(headersGetter());
].concat($http.defaults.transformRequest),
// placed custom transform ahead of $http default
transformResponse: [function (data, headersGetter)
$log.info(data);
$log.info(headersGetter());
data = tada:"Check your console";
return data;
].concat($http.defaults.transformResponse)
);
).
controller('myController', function(myService, $scope)
$scope.results = myService.get();
);
更新 要使用 JSONP,只需将方法切换到 JSONP。你可以阅读更多关于 ngResource here.
【讨论】:
我没有用 $resource 尝试过,但是在 $http transformResponse 发生在自动解析之后。因此,如果我的 JSON(或 XML 或其他)格式错误,它会在到达匿名函数之前出错,并且“数据”未定义。此外,无论我做什么,headersGetter 都是未定义的。这是 Angular 的哪个版本? 另外,$esource
扩展了 $http
,所以我相信您可能有同样的问题。
我花了一点时间,但我想出了如何让它工作。在 jsFiddle 示例中,我只是加载根 html 以演示错误的 JSON 响应。这是你要找的吗?
我显然错过了相关细节 - 我需要访问外部站点上的数据,所以我使用的是 JSONP。因此,问题出在 JSONP 回调代码中(这需要解析数据——有点——首先进行回调)。你知道解决这个问题的任何方法吗?
你们俩都准确地回答了我最初的问题,但这帮助我意识到,由于过于激进的“安全”限制,我想做的事情是不可能的。【参考方案3】:
角度文档是这样说的
要全局扩充或覆盖默认转换,请修改 $httpProvider.defaults.transformRequest 和 $httpProvider.defaults.transformResponse 属性。这些属性 默认情况下是一个转换函数数组,它允许您 将新的转换函数推入或取消转换到转换中 链。您还可以决定完全覆盖任何默认值 通过将您的转换函数分配给这些转换 属性直接没有数组包装。
基本上你需要做的是配置 $httpProvider
angular.module('myApp', [])
.config(['$httpProvider', function ($httpProvider)
//Define your transform function
//push your trasform function to the start of the array $httpProvider.defaults.transformResponse
//Or replace the transformResponse array with a function or a new array of tranform functions.
]);
现在您实现的 trasform 函数应该是数组中的第一个函数。由于那里已经有一个字符串到 JSON 转换函数。
【讨论】:
我已经尝试了几种不同的方法,但它似乎从未禁用任何引发解析错误的代码。我开始认为这可能是版本问题。直到明天我才能访问我的开发环境,所以一旦我有机会检查版本,我会更新你。 我检查了 angularjs 的源代码,它推送了默认的 tranformResponse,它将字符串转换为 json。如果错误不是由于转换为 JSON 而导致的,那么您必须提供更多详细信息\ 我显然错过了相关细节 - 我需要访问外部站点上的数据,所以我使用的是 JSONP。因此,问题出在 JSONP 回调代码中(这需要解析数据——有点——首先进行回调)。你知道解决这个问题的任何方法吗? 我猜没有办法在解析之前添加一个函数。以上是关于如何在 AngularJS 中插入命令或阻止 $http 的 JSONP 自动解析?的主要内容,如果未能解决你的问题,请参考以下文章
使用 AngularJS 拦截器阻止 HTTP 基本身份验证对话框