【问题标题】:MIME type checking error using AngularJS $http service and Coinbase API使用 AngularJS $http 服务和 Coinbase API 的 MIME 类型检查错误
【发布时间】:2014-04-08 20:48:31
【问题描述】:

我正在使用 AngularJS 创建一个简单的应用程序,它使用Coinbase API 显示 Coinbase 上比特币的当前即期汇率(价格)。

该应用在 Chrome、Safari、Firefox 和 Opera 中按预期运行,但在 Chrome Canary 和 IE 中我收到以下错误:

拒绝从执行脚本 'https://coinbase.com/api/v1/prices/spot_rate?callback=angular.callbacks._0' 因为它的 MIME 类型('application/json')是不可执行的,并且 已启用严格的 MIME 类型检查。

我熟悉 AngularJS,并且我使用 $http 服务来构建访问供应商 API 的其他应用程序,但我没有遇到过这个问题。

下面的代码应该通过 Coinbase API 获取即期汇率,将数据作为 $http 服务回调的一部分传递给范围,并通过每 60 秒进行一次后续调用来刷新存储在范围中的值。

angular.module('CoinbaseApp').controller('MainCtrl', function ($scope, $http, $interval) {

    $scope.getPrice = function(){
        $http.jsonp('https://coinbase.com/api/v1/prices/spot_rate?callback=JSON_CALLBACK').success(function(data){
            $scope.data = data;
        });
    };

    $scope.getPrice();

    $interval($scope.getPrice, 60000);
});

我的问题:严格的 MIME 类型检查问题是否与 Coinbase 服务 json 的方式有关?还是 AngularJS $http 服务和/或我如何请求数据的问题?

【问题讨论】:

    标签: javascript json angularjs api mime-types


    【解决方案1】:

    当调用的服务不响应适当的 CORS 标头并且不直接支持 JSONP,您可以安装 http 请求拦截器将请求重写为 GET https://jsonp.afeld.me/,将原始 URL 移动到 config.params(连同回调)。然后定义 responseTransform 以简单地提取并返回嵌入的 JSON:

    var app = angular.module('jsonp-proxy-request-interceptor', []);
    app.service('jsonpProxyRequestInterceptor',
        function JsonpProxyRequestInterceptor($log) {
      var callbackRx = /callback\((.+)\);/gm;
      this.request = function(config) {
        if (config.url === 'https://api.domain.com/' && config.method === 'GET') {
          var apiUrl = config.url;
          config.url = 'https://jsonp.afeld.me/';
          config.params = angular.extend({}, config.params || {}, {
            url: apiUrl,
            callback: 'callback'
          });
          config.transformResponse.unshift(function(data, headers) {
            var matched = callbackRx.exec(data);
            return matched ? matched[1] : data;
          });
        }
        return config;
      };
    });
    app.config(['$httpProvider', function configHttp($httpProvider) {
      $httpProvider.interceptors.push('jsonpProxyRequestInterceptor');
    }]);
    

    您也可以从 https://gist.github.com/mzipay/69b8e12ad300ecaa467a 获取此示例的要点。

    【讨论】:

    • 角度服务是一个很棒的解决方案,但是如果您将代码嵌入到您的答案中会非常有用。
    【解决方案2】:

    对于那些询问,我能够通过节点中的 JSON 代理解决我的问题。

    https://github.com/afeld/jsonp

    Coinbase REST API 仅通过 GET 请求提供 JSON 端点,而不是 JSONP(通常作为 CORS 替代方案提供)。如果没有 JSONP,您将无法向其域发出跨域请求,因为未设置 Allow Access 标头(很可能是出于安全原因)。

    使用节点服务器端代理允许我通过代理向客户端发出请求作为普通的 GET 请求,因为节点代理提供了带有正确标头的请求的返回结果。

    Heroku provides a good tutorial for installing node apps,使代理端点公开可用。

    【讨论】:

    • 如果您能详细说明您的答案,我将不胜感激。谢谢
    猜你喜欢
    • 2011-06-23
    • 2016-08-23
    • 2015-10-05
    • 2020-07-13
    • 2018-11-16
    • 2013-03-07
    • 2019-08-04
    • 2016-05-20
    • 1970-01-01
    相关资源
    最近更新 更多