如何在 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 基本身份验证对话框

如何使用angularjs在mongodb中插入特定的数组值

AngularJS和跨域请求被阻止[关闭]

使用AngularJS单击添加按钮时如何在表中插入新数据行

在没有要插入的数据时阻止查询插入

如何阻止 Visual Studio 在我的代码中插入不可编辑的空白行