拒绝从 '*' 执行脚本,因为它的 MIME 类型 ('application/json') 不可执行,并且启用了严格的 MIME 类型检查
Posted
技术标签:
【中文标题】拒绝从 \'*\' 执行脚本,因为它的 MIME 类型 (\'application/json\') 不可执行,并且启用了严格的 MIME 类型检查【英文标题】:Refused to execute script from '*' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled拒绝从 '*' 执行脚本,因为它的 MIME 类型 ('application/json') 不可执行,并且启用了严格的 MIME 类型检查 【发布时间】:2014-09-28 04:31:03 【问题描述】:我是 AngularJS 的新手。我正在使用 rails 应用程序以 json 格式公开数据。数据将由 Angular 应用程序使用。 angular repo 和 rails repo 是完全不同的。不同存储库的原因是因为我希望我的 Rails 存储库只是使用我可以在 Angular 应用程序中使用的 API 公开数据。
我的rails控制器如下
class Api::V1::PhonesController < ApplicationController
def index
render json: Phone.all
end
def show
render json: Phone.find(params[:id])
end
...
end
现在,当我访问“localhost:3000/api/v1/phones”时,它会返回所有手机的 json 数据。当我访问 'localhost:3000/api/v1/phones/1' 时,它返回 id 为 1 的手机的 json 数据。我使用http://jsonlint.com/ 验证了 json 数据格式。到这里为止一切正常。
我的 angularjs 路由文件如下:
$routeProvider.
when('/phones',
templateUrl: 'list.html',
controller: 'PhoneListController'
).
when('/phones/:id',
templateUrl: 'show.html',
controller: 'PhoneShowController'
).
otherwise(
redirectTo: '/phones'
);
]);
我在 Angular 存储库中的 index.html 中嵌入了 list.html 模板。
<html ng-app='phoneCatApp'>
...
</html>
<script type="text/ng-template" id="list.html">
This is the list template.
</script>
services.js 的代码如下:
var appServices = angular.module('appServices', []);
phoneCatApp.factory('appServices', ['$http', '$q', function($http, $q)
var url = "http://localhost:3000/api/v1/";
//get all phones
this.getPhones = function()
var defered = $q.defer();
var listApi = url + "phones";
$http.jsonp(listApi).then(function(results)
defered.resolve(results);
, function(error)
defered.reject(error);
);
return defered.promise;
return this;
]);
当我访问“#/phones”时,脚本模板中的文本也会显示出来。问题是 1)在chrome中,当我检查页面时显示以下错误。
Refused to execute script from 'http://localhost:3000/api/v1/phones' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.
2) 在 Firefox 中,显示以下错误。
SyntaxError: missing ; before statement
感谢您的帮助。
【问题讨论】:
【参考方案1】:嘿,所以我相信您的问题是您的 Rails 控制器返回的是 JSON 而不是 JSONP。您的控制器必须明确指定一个回调函数,该函数可以由请求参数指定。
有关从 rails 控制器返回 JSONP 的示例,请参阅 Handling jsonp in rails 3 controller
所以你的rails代码看起来像(啊,我的rails非常生锈......):
class Api::V1::PhonesController < ApplicationController
def index
if params[:callback]
format.js render :json => :phones => Phone.all.to_json, :callback => params[:callback]
else
format.json render json: :phones => Phone.all.to_json
end
end
那么对于角度方面,这个答案应该可以帮助你: parsing JSONP $http.jsonp() response in angular.js
我认为你的角度看起来像:
var appServices = angular.module('appServices', []);
phoneCatApp.factory('appServices', ['$http', '$q', function($http, $q)
var url = "http://localhost:3000/api/v1/";
//get all phones
this.getPhones = function()
var defered = $q.defer();
var listApi = url + "phones?callback=JSON_CALLBACK";
$http.jsonp(listApi).then(function(results)
defered.resolve(results);
, function(error)
defered.reject(error);
);
return defered.promise;
return this;
]);
【讨论】:
出现错误:“ActionController::InvalidCrossOriginRequest(安全警告:另一个站点上的嵌入式 假设有一个服务将 json 数据导出到很多应用程序。在这里,我无法修改服务器代码以考虑回调。将要使用 json 数据的应用程序需要处理它。那怎么办? 所以这可能作为一个单独的问题更好,甚至可能在 securityexchange 上,但文档在这里:edgeapi.rubyonrails.org/classes/ActionController/…guides.rubyonrails.org/…(一个好的 Rails 安全指南)......基本上,实现好的 csrf想要提供 JSONP 端点时的保护有点棘手,需要仔细考虑。应用程序/消费者是否将位于与 REST 服务器不同的域中?一个好的开始:***.com/questions/613962/is-jsonp-safe-to-use 应用程序/消费者将是不同的应用程序。我的 Angular 应用程序主题基于官方 angularjs 教程(手机目录)应用程序。唯一的区别是教程使用存储在应用程序中的 json 文件来检索数据,而我使用的是 rails 应用程序来使用 API 公开数据。 老实说,如果您有兴趣拥有一个安全的应用程序,我会使用 CORS(跨域请求共享)而不是 JSONP。这样,您的 REST 服务器实际上可以选择特定域来允许跨域请求。另外 - 您可以使用 Angular 的 CSRF 保护和标头中的令牌,您可以在 Rails 端检查这些令牌。以上是关于拒绝从 '*' 执行脚本,因为它的 MIME 类型 ('application/json') 不可执行,并且启用了严格的 MIME 类型检查的主要内容,如果未能解决你的问题,请参考以下文章
拒绝从 URL 执行脚本,因为它的 MIME 类型 ('application/json') 不可执行,并且启用了严格的 MIME 类型检查
拒绝从 'url' 执行脚本,因为它的 MIME 类型('application/json')不可执行
拒绝从 'URL' 执行脚本,因为它的 MIME 类型 ('text/html') 不可执行,并且启用了严格的 MIME 类型检查
拒绝从 'file_name.php' 执行脚本,因为它的 MIME 类型 ('text/html') 不可执行,并且启用了严格的 MIME 类型检查