http.jsonp 和 JavaScript 中的回调

http.jsonp and callbacks in javascript

本文关键字:回调 JavaScript jsonp http      更新时间:2023-09-26

我正在研究一个计算器,该计算器将考虑AWS实例成本。我正在从亚马逊上的.js文件中提取数据,我想将其读取到对象中,但不断收到错误"未捕获的引用错误:未定义回调"..这是我.js文件。

(function() {
  var app = angular.module('formExample', []);
  var ExampleController = function($scope, $http) {
    $scope.master = {};
    $scope.update = function(user) {
      $scope.master = angular.copy(user);
      $scope.GetAws();
    };
    $scope.reset = function() {
      $scope.user = "";
    };
    function callback(data) {
      $scope.aws = data;
    }
    $scope.GetAws = function() {
      var url = "http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js?callback=callback";
      $http.jsonp(url);
    };
    $scope.reset();
  };
  app.controller('ExampleController', ['$scope', '$http', ExampleController]);
}());

奇怪的是,您使用的 aws 链接支持 jsonp,但它不接受自定义回调函数名称。(至少您可以查找以了解他们正在寻找的查询字符串是否callback)。当我们提供callback=JSON_CALLBACK时,Angular 会处理它,它会被转换为由 angular 临时全局公开的angular.callbacks_x来处理请求并相应地解决承诺。但为此,端点必须采用回调参数并将响应包装在相同的字符串和函数调用中。但是,此端点似乎没有考虑它,即使没有任何回调,它也会自动包装为默认的callback函数调用。因此,您需要注入$window(正确的DI方式)对象并为其设置callback功能,?callback=callback无关紧要。

  var ExampleController = function($scope, $http, $window) {
    $scope.master = {};
    //....
    $window.callback = function(data) {
      $scope.aws = data;
    }
    $scope.GetAws = function() {
      var url = "http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js?callback=callback";
      $http.jsonp(url);
    };
    $scope.reset();
   };
   app.controller('ExampleController', ['$scope', '$http', '$window', ExampleController]);

普罗提

这是因为AWS脚本希望在全局范围内(Angular之外)调用一个名为"callback"的函数。由于您的函数在另一个 (IIFE) 函数的范围内,因此无法访问它。

在这种情况下,我所做的只是将函数放在全局范围内。

如果应用程序需要加载一些 API,然后 Angular 才能发挥它的魔力,并且具有类似于您的情况的回调,我已经完成了以下操作,手动引导 Angular:

索引.html

<script src="http://www.example.com/api?callback=myCallbackFunction"></script>

应用.js

// callback function, in global (window) scope
function myCallbackFunction() {
  // manually bootstrap Angular
  angular.element(document).ready(function() {
    angular.bootstrap(document, ['myApp']);
  });
}

// your IIFE
(function() {
})();

注意callback应该设置在window范围内。因此,一种解决方案如下:

$scope.reset = function() {
  $scope.user = "";
};
window.callback = function(data) {
  $scope.aws = data;
}
$scope.GetAws = function() {
  var url = "http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js?callback=callback";
  $http.jsonp(url);
};