【问题标题】:AngularJS request JSON from other domainAngularJS 从其他域请求 JSON
【发布时间】:2015-11-01 04:37:08
【问题描述】:

我正在尝试使用以下代码从 Wikia API 检索数据。但一切似乎都失败了。据我了解,必须在服务器上启用 CORS,我试图从中检索数据。但是我不知道Wikia是否是这种情况。所以 JSONP 似乎是唯一的方法。但我得到了错误

XMLHttpRequest cannot load http://adventuretime.wikia.com/api/v1/Articles/List?expand=1&category=Episodes&limit=200. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://website.com' is therefore not allowed access.

我已阅读 AngularJS 文档:https://docs.angularjs.org/api/ng/service/$http

w3schools:http://www.w3schools.com/angular/angular_http.asp

还有很多关于 stackoverflow 的问题。我的代码有什么可怕的问题吗? Angular 应该原生支持 CORS 和 JSONP 请求

我的代码如下:

Index.html

<!DOCTYPE html>
<html ng-app="episodes">
<head>
    <meta charset="UTF-8">
    <title>Episodes</title>
    <script src="angular.js"></script>
    <script src="workshop.js"></script>
</head>
<body ng-controller="AppController as app">

    <table>
        <thead> 
            <tr>
                <th>Title</th>
                <th>Url</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="episode in app.episodes">
                <td>{{episode.title}}</td>
                <td>{{episode.url}}</td>
            </tr>
        </tbody>
    </table>

</body>
</html>

workshop.js

(function(){
    angular
        .module('episodes', [])
        .controller('AppController', function($http){
            var app = this;

            app.episodes = $http({
                url: "http://adventuretime.wikia.com/api/v1/Articles/List?expand=1&category=Episodes&limit=200",
                dataType: "jsonp"
            });

        });
})();

感谢任何帮助!

提前感谢您的帮助

编辑

响应标头是:

Content-Encoding: gzip
X-Content-Type-Options: nosniff
X-Cacheable: YES
Age: 0
X-Cache: ORIGIN, MISS, MISS
Content-Length: 21965
X-Served-By: ap-s21, cache-wk-sjc3160-WIKIA, cache-fra1233-FRA
X-Backend-Response-Time: 2.267
Server: Apache
X-Timer: S1439118796.704444,VS0,VE2447
Vary: Accept-Encoding
Content-Type: application/json; charset=utf-8
Cache-Control: public, max-age=86400
Accept-Ranges: bytes
X-Cache-Hits: ORIGIN, 0, 0

【问题讨论】:

  • JSONP 也必须得到服务器的支持。 (返回的 JS sn-p 需要调用你的回调。)
  • @Noah 你能解释一下回调吗?服务器似乎支持 JSONP,但我现在收到 MIME 错误
  • 关于该主题的维基百科文章解释:en.wikipedia.org/wiki/JSONP

标签: javascript ajax json angularjs cors


【解决方案1】:

尝试使用$http.jsonp(url); 进行跨域请求;

Angularjs api - $http.jsonp();

【讨论】:

  • 哇 - 它似乎工作,让我请求数据!我会认为速记 jsonp 方法将等于 dataType: "jsonp" 方式。使用我的代码:app.fetch = function() { $http.jsonp("http://adventuretime.wikia.com/api/v1/Articles/List?expand=1&amp;category=Episodes&amp;limit=200&amp;callback=JSON_CALLBACK") .then(function(results){ return results.data.items; }); }; 它会引发错误:Refused to execute script from '*&amp;callback=JSON_CALLBACK' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled. 再次感谢
  • @KlamHuggeren 然后使用你的服务器。只是:echo file_get_contents('http://adventuretime.wikia.com/api/v1/Articles/List?expand=1&amp;category=Episodes&amp;limit=200'); 在 PHP 上和 $http.get('link_to_You_fn').success(function(data){}); 在 JS 上;
  • 你是对的!我在 Angular 控制器中使用 file_get_contents 方法和 $http.get 制作了 php 文件。 $http.get('get.php').success(function(results){ app.episodes = results.items; });
【解决方案2】:

据我了解,必须在服务器上启用 CORS

正确。

但是我不知道 Wikia 是不是这样。

由于您收到错误消息:

没有“Access-Control-Allow-Origin”标头

……它没有启用。


所以 JSONP 似乎是唯一的方法。

JSONP 是一种解决同源策略的技巧。它不像 CORS(旨在提供显式权限)那样优雅,但它要求服务器以 JSONP 形式表达数据。

错误信息:

拒绝执行来自 '*&callback=JSON_CALLBACK' 的脚本,因为它的 MIME 类型 ('application/json') 不可执行,并且启用了严格的 MIME 类型检查。

表示对 HTTP 请求的响应不是 JSONP(会有application/javascript Content-Type),所以服务器不支持。


未经发出请求的网站的明确许可,网站无法指示网络浏览器向另一台服务器发出 HTTP 请求并将响应提供给其 JavaScript。

您需要查看一个替代方案,其中对服务器的请求不是来自浏览器。例如通过您自己的服务器代理请求。

【讨论】:

  • 非常感谢@Quentin! :) 所以唯一的方法是代理请求。你能链接到一些关于这个主题的阅读材料吗?为简单的 JSON 请求创建代理服务器似乎有点过头了?
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2018-01-05
  • 2014-04-28
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 2016-06-23
相关资源
最近更新 更多