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>
当我尝试在 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 thejsonpCallbackParam
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>