Javascript Ember.js Ember data restadapter无法加载json
干杯! 我有余烬数据存储:Javascript Ember.js Ember data restadapter无法加载json,javascript,json,ember.js,ember-data,Javascript,Json,Ember.js,Ember Data,干杯! 我有余烬数据存储: TravelClient.Store = DS.Store.extend({ revision: 11, adapter: DS.RESTAdapter.create({ bulkCommit: false, url: "http://someIP:somePORT"}) }); 和路由器: TravelClient.ToursRoute = Ember.Route.extend({ model: function() { return Trav
TravelClient.Store = DS.Store.extend({
revision: 11,
adapter: DS.RESTAdapter.create({ bulkCommit: false, url: "http://someIP:somePORT"})
});
和路由器:
TravelClient.ToursRoute = Ember.Route.extend({
model: function() {
return TravelClient.Tour.find();
}
});
我从远程服务器接收此JSON:
{
"tours": [
{
"id": "5110e8b5a8fefe71e0000197",
"title": "qui deserunt dolores",
"description": "Id velit nihil.",
"seats": 12,
"options": [
],
"images": [
{
"id": "5110e8b5a8fefe71e0000196",
"url": "url"
}
}
但是当我尝试返回TravelClient.Tour.find()
时失败,原因是:
http://someIP:somePORT/tours 404 (Not Found)
XMLHttpRequest cannot load http://someIP:somePORT/tours. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.
RESTAdapter似乎不知道,它必须接收JSON还是什么
更新:
在rails服务器端的应用程序控制器中:
def set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Request-Method'] = '*'
end
但它仍然是:
OPTIONS http://someIP:somePORT/tours 404 (Not Found)
看起来RESTAdapter试图加载tours资源,而不是tours.json:
Request URL:http://someIP:somePORT/tours
工作解决方案
扩展重新适应程序:
TravelClient.CUSTOMAdapter = DS.RESTAdapter.extend({
bulkCommit: false,
url: "http://remote_server_address",
buildURL: function(record, suffix) {
var s = this._super(record, suffix);
return s + ".json";
}
})
并使用正确的标题响应选项请求,
RESTAdapter
需要JSON
这不是问题,但页面和JSON不在同一个域中,这是一个安全问题。您可以使用以下两种解决方案之一解决此问题
您遇到的问题是,您应该使用JSONP
或CORS
。最快的修复方法可能是告诉余烬数据您想要使用JSONP
对于CORS
,您的服务器需要使用标题响应选项
请求:
Access Control Allow Origin
访问控制请求方法
rackcors
see或
您可以通过覆盖RESTAdapter
中的ajax
钩子来实现这一点,如下所示:
App.store = DS.Store.create({
revision: 11,
adapter: DS.RESTAdapter.create({
namespace: "data",
url: "",
ajax: function (url, type, hash) {
hash.url = url;
hash.type = type;
hash.dataType = 'jsonp';
hash.contentType = 'application/json; charset=utf-8';
hash.context = this;
if (hash.data && type !== 'GET') {
hash.data = JSON.stringify(hash.data);
}
jQuery.ajax(hash);
},
})
});
我在Rails中有一个简单的解决方案(到目前为止,它对我来说是有效的)。它虽然不整洁,但可以通过控制器中的逻辑轻松地收紧 在
routes.rb中
:
match ':path' => 'authentications#allow', constraints: {method: 'OPTIONS'}
它只是将状态OK
返回给任何选项
请求
def allow
head :ok
end
然后在application\u controller.rb
中为每个请求设置跨源资源共享(CORS)头:
before_filter :cors
def cors
response.headers.merge! 'Access-Control-Allow-Origin' => '*', 'Access-Control-Allow-Methods' => 'POST, PUT, GET, DELETE', 'Access-Control-Allow-Headers' => 'Origin, Accept, Content-Type'
end
如果您希望使用JSONP,那么重写private
ajaxOptions
函数要比使用jQuery
和重写ajax
方法容易得多。Ember的管道包括删除jQuery依赖项。因此,请改为:
适配器/application.js
:
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
ajaxOptions: function(url, type, options) {
var hash = this._super(url, type, options);
hash.dataType = "jsonp";
return hash;
}
});
如果Ember核心团队能够公开一个公共方法来正式支持这一点(而不是黑客攻击一个私有api),这将是一个非常好的选择
要使用CORS,我只需要将smth添加到服务器的响应头中,如
访问控制允许源:
?是的,请参见此处:此处:您可以更具体地控制允许的内容。Rack CORS gem只是用于更具体的定制,而不是我目前需要的,但是感谢您的关注。您需要以某种方式使用标题响应选项请求。但是我的服务器响应选项请求时,我有正确的标题响应。您设置的标题将与GET
请求一起返回。您需要使用OPTIONS
requestRack CORS gem返回它们,谢谢。我认为它只是“开箱即用”地处理选项请求。这是下一个访问者FTWB的链接,但我的标题没有问题,只是Rails返回html,而我需要json。所以解决方法就是直接告诉Rails您需要json-extend适配器的buildURL方法。对不起我的英语。