AngularJS 中 $http 的 HTTP JSONP 请求问题

HTTP JSONP request issue with $http in AngularJS

当我尝试在 angularJS 中使用 JSONP 方法时出现以下错误。

Uncaught SyntaxError: Unexpected token : http://example.com/getSomeJson?format=jsonp&json_callback=angular.callbacks._0

我在这里做错了什么,这是我的 AngularJs 带有 http 请求的控制器:

更新问题详情

请参阅下面的代码片段,它重现了我的问题,我评论了一些 .js 来说明我到目前为止所做的尝试。

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

app.controller('mainController', ['$http', 'mainService', function($http, mainService){

 mainCtrl = this;

 mainCtrl.test = "If you can see this the mainController works"

 var promise = mainService.getJson();
 promise.then(function (data)
 {
  mainCtrl.json = data;
 });
}]);

app.service("mainService", function ($http, $q)
{
  var deferred = $q.defer();
 
    /*  
    // Method to Grab JSON that has CORs enabled:
    // JSON resource with CORs enabled
 var url = 'https://jsonplaceholder.typicode.com/posts/1';
 $http({
     method: 'GET',
     cache: true,
     url: url,
           headers: {  
           'Content-Type': 'application/json;charset=UTF-8'  
       }
 }).
 success(function(response) {
     //your code when success
     deferred.resolve(response);
     console.log('HTTP CORS SUCCESS!');
 }).
 error(function(response) {
     //your code when fails
     console.log('HTTP CORS ERROR!');
 });
*/ 


 /* */
    // Method to Grab JSON that has CORs enabled:
 // JSON resources without CORs enabled
 var url = 'http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json' // does not work?
    // var url = 'http://samcroft.co.uk/json-data/sample'  // this one works

 $http({
        method: 'jsonp',
        url: url + '?callback=JSON_CALLBACK',
    }).
 success(function(response) {
     //your code when success
     deferred.resolve(response);
     console.log('JSONP SUCCESS!');
 }).
 error(function(response) {
     //your code when fails
     console.log('JSONP ERROR!');
 });


 
 this.getJson = function ()
 {
  return deferred.promise;
 };


});
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
 <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular-route.js"></script>
 <script src="app.js"></script>
</head>
<body ng-controller="mainController as mainCtrl">
 <p>{{mainCtrl.test}}</p>
 <hr />
 <p>You should also see the JSON obeject below:</p>
 {{mainCtrl.json}}
</body>
</html>

原始问题详情

app.controller('testController', ['$scope', '$http', function($scope, $http){

    var url = 'http://example.com/getSomeJson';

    $http({
        method: 'JSONP',
        url: url,
        params: {
            format: 'jsonp',
            json_callback: 'JSON_CALLBACK'
        }
    }).
    success(function(data) {
        //your code when success
        $scope.data = data;
        console.log('SUCCESS!');
    }).
    error(function(status) {
        //your code when fails
        console.log('ERROR!');
    });
}]);

当我查看 chrome 源面板中的 json 时,我看到错误突出显示的位置。

知道我做错了什么吗?还是 API 服务的配置方式有问题?

JSONP callback must be specified by jsonpCallbackParam

BREAKING CHANGE

You can no longer use the JSON_CALLBACK placeholder in your JSONP requests. Instead you must provide the name of the query parameter that will pass the callback via the jsonpCallbackParam property of the config object, or app-wide via the $http.defaults.jsonpCallbackParam property, which is "callback" by default.

-- 添加到 AngularJS v1.6.0-rc.2


更新

OP 示例代码不起作用,因为 http://run.plnkr.co API 不支持 JSONP。

JSONP 仅在 API 早于 ACCESS-CONTROL headers 的某些网站上可用。

有关详细信息,请参阅 JSONP Demystified

给你:-)

您使用 jsonp 请求尝试的代码看起来不错,但是您使用的 url 不支持 jsonp 请求,这就是您出错的原因。

如果您用 $http.get 尝试相同的 url,它会正常工作。

为了支持 jsonp 调用,响应应该用 JSON_CALLBACK () 包裹起来,如下所示

JSON_CALLBACK ({ /* JSON */ })

因此,我将其更改为有效 jsonp url 并且有效!

https://angularjs.org/greet.php?callback=JSON_CALLBACK

您可以在浏览器中尝试这个 url 并查看响应,它是如何用 JSON_CALLBACK () 包装的。

但是如果你尝试下面的 url,你可以看到没有任何包装的 json

http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json?callback=JSON_CALLBACK

这就是看api是否支持jsonp的区别。

此外,我已经使用与另一个 SO 问题答案相同的语法更改了下面的 service

工作片段

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

app.controller('mainController', ['$http', 'mainService', function($http, mainService){

 mainCtrl = this;

 mainCtrl.test = "If you can see this the mainController works"

 var promise = mainService.getJson();
 promise.then(function (data)
 {
  mainCtrl.json = data;
 });
}]);

app.service("mainService", function ($http, $q)
{
    var deferred = $q.defer();
 var url = 'https://angularjs.org/greet.php';
 //var url = 'http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json';
 
    /*  
    // Method to Grab JSON that has CORs enabled:
    // JSON resource with CORs enabled
 var url = 'https://jsonplaceholder.typicode.com/posts/1';
 $http({
     method: 'GET',
     cache: true,
     url: url,
           headers: {  
           'Content-Type': 'application/json;charset=UTF-8'  
       }
 }).
 success(function(response) {
     //your code when success
     deferred.resolve(response);
     console.log('HTTP CORS SUCCESS!');
 }).
 error(function(response) {
     //your code when fails
     console.log('HTTP CORS ERROR!');
 });
*/ 


 /* */
    // Method to Grab JSON that has CORs enabled:
 // JSON resource without CORs enabled
  function getJson() {

 // $http.jsonp(url + "?callback=JSON_CALLBACK").  // this does not work either
 $http.jsonp(url + '?callback=JSON_CALLBACK').
 then(function(response) {
     //your code when success
     deferred.resolve(response);
     console.log('JSONP SUCCESS!');
 }, function(response) {
     //your code when fails
     console.log('JSONP ERROR!');
        deferred.reject(response);
 });
 
    return deferred.promise;

  }
 
 this.getJson = getJson;


});
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
 <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular-route.js"></script>
 <!--<script src="app.js"></script>-->
</head>
<body ng-controller="mainController as mainCtrl">
 <p>{{mainCtrl.test}}</p>
 <hr />
 <p>You should also see the JSON obeject below:</p>
 {{mainCtrl.json}}
</body>
</html>