我正在使用AngularJS创建一个简单的应用程序,该应用程序使用Coinbase API在Coinbase上显示比特币的当前现货汇率(价格)。
该应用程序在Chrome,Safari,Firefox和Opera中按预期工作,但是在Chrome Canary和IE中,我收到以下错误:
拒绝执行来自的脚本 "https://coinbase.com/api/v1/prices/spot_rate?callback=angular.callbacks._0" 因为它的MIME类型("应用程序/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服务和/或我请求数据的方式有问题?
当调用不使用适当的 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 分叉此示例的要点。
对于那些询问的人,我能够通过节点中的 JSON 代理解决我的问题。
https://github.com/afeld/jsonp
Coinbase REST API仅通过GET请求提供JSON端点,而不是JSONP(通常作为CORS替代方案提供)。如果没有 JSONP,则无法向其域发出跨域请求,因为未设置允许访问标头(很可能是出于安全原因)。
使用节点服务器端代理允许我通过代理将请求客户端作为正常的 GET 请求,因为节点代理提供了带有正确标头的请求返回结果。
Heroku 为安装节点应用程序提供了一个很好的教程,使代理端点公开可用。