javascript Ember.js ember-data 重新适配器无法加载 json

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14828478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 22:41:07  来源:igfitidea点击:

Ember.js ember-data restadapter fail to load json

javascriptjsonember.jsember-data

提问by xamenrax

Cheers! I have ember-data store:

干杯! 我有余烬数据存储:

TravelClient.Store = DS.Store.extend({
  revision: 11,
  adapter: DS.RESTAdapter.create({ bulkCommit: false, url: "http://someIP:somePORT"})
});

And router:

和路由器:

TravelClient.ToursRoute = Ember.Route.extend({
  model: function() {
    return TravelClient.Tour.find();
  }
});

I recieve this JSON from remote server:

我从远程服务器收到这个 JSON:

{
  "tours": [
    {
      "id": "5110e8b5a8fefe71e0000197",
      "title": "qui deserunt dolores",
      "description": "Id velit nihil.",
      "seats": 12,
      "options": [

      ],
      "images": [
        {
          "id": "5110e8b5a8fefe71e0000196",
          "url": "url"
        }
}

But when I try to return TravelClient.Tour.find()it fails with:

但是当我尝试return 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.

IT seems like RESTAdapter doesn't know, that it must receive JSON or what?

它似乎 RESTAdapter 不知道,它必须接收 JSON 还是什么?

UPDATE:

更新:

In the application controller on the rails server-side:

在 rails 服务器端的应用程序控制器中:

def set_access_control_headers
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Request-Method'] = '*'
end

But it's still :

但它仍然是:

OPTIONS http://someIP:somePORT/tours 404 (Not Found)

And it looks like RESTAdapter tries to load tours resource, not tours.json:

看起来 RESTAdapter 尝试加载 tours 资源,而不是 tours.json:

Request URL:http://someIP:somePORT/tours

WORKING SOLUTION

工作解决方案

Extend RESTAdapter:

扩展 RESTAdapter:

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";
  }
})

and respond to an OPTIONS request with right headers

并使用正确的标头响应 OPTIONS 请求

采纳答案by albertjan

The RESTAdapterexpects JSONthat is not the problem but the page and the json are not on the same domain, this is a security issue. You can resolve this by using one of the two solutions named below.

RESTAdapter预计JSON认为是没有问题的,但页面和JSON不在同一个域中,这是一个安全问题。您可以使用下面命名的两种解决方案之一来解决此问题。

You're running into the same origin policyyou should either use JSONPor CORS. The quickest fix would probably be to tell ember-data that you want to use JSONP.

您遇到了应该使用或 的同源策略。最快的解决方法可能是告诉 ember-data 您要使用.JSONPCORSJSONP

For CORSyour server needs to respond to an OPTIONSrequest with the headers:

因为CORS您的服务器需要OPTIONS使用标头响应请求:

  • Access-Control-Allow-Origin
  • Access-Control-Request-Method
  • Access-Control-Allow-Origin
  • Access-Control-Request-Method

i'm no rails expert but you will probably need to do something with the gem rack-corssee hereor here.

我不是 Rails 专家,但您可能需要对 gem 做一些事情,rack-cors请参阅此处此处

You could do that by overriding the ajaxhook in the RESTAdapterlike so:

你可以通过像这样覆盖ajax钩子来做到这RESTAdapter一点:

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);
        },
    })
});

回答by Baruch

I have a simple work around in Rails (that is working for me so far.) It is untidy as is, but can easily be tightened up with logic in the controllers.

我在 Rails 中有一个简单的工作(到目前为止对我有用。)它原样不整洁,但可以很容易地用控制器中的逻辑收紧。

In routes.rb:

routes.rb

match   ':path' => 'authentications#allow', constraints: {method: 'OPTIONS'}

Which simply returns status OKto any OPTIONSrequest.

这只是将状态返回OK给任何OPTIONS请求。

def allow
  head :ok
end

And then in application_controller.rbset the Cross-origin resource sharing (CORS) headers for every request:

然后application_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

回答by Jamie Chong

If you are looking to use JSONP it's much easier to override the private ajaxOptionsfunction instead of using jQueryand overriding the ajaxmethod. Ember's pipeline includes the removal of the jQuery dependency. So do this instead:

如果您希望使用 JSONP,那么覆盖私有ajaxOptions函数而不是使用jQuery和覆盖该ajax方法要容易得多。Ember 的管道包括删除 jQuery 依赖项。所以改为这样做:

adapters/application.js:

adapters/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;
    }
});

It would be create if the Ember core team could expose a public method to officially support this (instead of hacking a private api).

如果 Ember 核心团队可以公开一个公共方法来正式支持这一点(而不是破解一个私有 api),那将是创建的。

https://github.com/emberjs/data/blob/1.0.0-beta.15/packages/ember-data/lib/adapters/rest_adapter.js#L915

https://github.com/emberjs/data/blob/1.0.0-beta.15/packages/ember-data/lib/adapters/rest_adapter.js#L915