无法使用 AngularJS $http.json/get 从远程服务器获取 JSON


Can't get JSON from remote server with AngularJS $http.json/get

我在从远程服务器使用 AngularJS 获取远程 JSON 文件时遇到了真正的麻烦,即使我得到它,我也找不到使用数据的方法。

这是角度代码:

 var artistControllers = angular.module('artistControllers', ['ngAnimate']);
artistControllers.controller('ListController', ['$scope', '$http', function($scope, $http) {
    $http.json('http://remotehost.mobi/temp.json').
        success(function(data){
            console.log('success');
            console.log(data);
    }).
        error(function(data, status ){
            console.log('error');
            console.log('status');
    });
}]);

通常我得到的只是所有类型的错误:

  • 尝试从 PHP 脚本获取动态 JSON 时,我需要发送一个回调,有时有效,但回调会触发函数这超出了范围,因此与我的需求无关。
  • 尝试从 .json 文件加载 JSON 时(如示例中所示)我得到错误。
  • 使用 $http.get 时,我总是获得跨域安全性
    消息。

我正在寻找一种从远程服务器加载 json 数据的方法,该服务器由 PHP 动态生成,带有角度 JS 控制器并在该控制器内使用它。

谢谢

您需要

更改服务器以允许 CORS(请参阅此处)或使用$http.jsonp并将响应更改为 JSONP 格式(包装在回调函数调用中的 JSON 正文)。

如果不控制远程服务器,则可以通过自己的服务器代理请求,使其不再是跨域的。

启用 CORS 的代理示例如下 corsproxy.com

CORE比jsonp更安全,因为它无法执行javascript代码。从好的方面来说,您可以使用CORS更好地控制状态更改/超时/进度和堕胎,因为它现在是ajax

现在唯一的风险是你相信 corsproxy.com 会读取正在传递的数据吗?

您唯一需要做的就是将http://替换为http://www.corsproxy.com/(不要认为它适用于https...

var artistControllers = angular.module('artistControllers', ['ngAnimate']);
artistControllers.controller('ListController', ['$scope', '$http', function($scope, $http) {
    $http.json('http://www.corsproxy.com/kinneret.mobi/temp.json').
        success(function(data){
            console.log('success');
            console.log(data);
        }).
        error(function(data, status ){
            console.log('error');
            console.log('status');
        });
}]);

感谢您的帮助。我想我的问题有点不同,这就是我发布此解决方案的原因。

Evantualy 我添加了一个新的标头,以允许跨源到动态生成 JSON 代码的 PHP:

header('Access-Control-Allow-Origin: *');
header('content-type: application/json; charset=utf-8');

这在函数编码之前并返回 json。我添加的另一件事是在发送回 JSON 之前对其进行格式化。我发现将"原始"未格式化的 JSON 发回会导致意外问题。从 PHP 5.4 开始,您可以在json_encode中添加JSON_PRETTY_PRINT:

echo  json_encode($data_array, JSON_PRETTY_PRINT);

在角度代码中,我检查了许多组合,包括@Endless建议使用 corsproxy.com,但发现经过这些调整后您可以简单地使用$http.get

如果有人在此跨域策略中遇到奇怪的问题,希望这会有所帮助。