2013-02-12 4 views
11

Beifall laden! Ich habe glut-Datenspeicher:Ember.js glut-Daten restadapter scheitern json

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

und Router:

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

Ich erhalte diese JSON von Remote-Server:

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

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

Aber wenn ich zu return TravelClient.Tour.find() versuchen, es irgendwie:

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. 

Es scheint, als ob RESTAdapter nicht weiß, dass er JSON empfangen muss oder was?

UPDATE:

In der Anwendungssteuerung auf den Schienen serverseitigen:

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

Aber es ist immer noch:

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

Und es sieht aus wie RESTAdapter Touren zu laden versucht Ressource, nicht tours.json:

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

Arbeitslösung

RESTAdapter Extend:

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

und reagieren auf eine OPTIONS-Anforderung mit der rechten Header

+0

der Header Sie setzen mit dem 'GET' Wunsch zurück Sie sie mit einem' OPTIONS' Anfrage – albertjan

+0

Rack-CORS Juwel haben den Trick, dank zurückgeben müssen. Ich denke, es macht all das mit OPTIONS-Anfragen einfach "out of the box". – xamenrax

+0

Heres ist der Link für den nächsten Besucher https://github.com/cyu/rack-cors ftw – genkilabs

Antwort

10

Die RESTAdapterJSON erwartet, das ist nicht das Problem, sondern die Seite und die json sind nicht auf der gleichen Domain, dies ist ein Sicherheitsproblem. Sie können dies beheben, indem Sie eine der beiden unten genannten Lösungen verwenden.

Sie laufen in die same origin policy Sie sollten entweder JSONP oder CORS verwenden. Die schnellste Lösung wäre wahrscheinlich, ember-data mitzuteilen, dass Sie JSONP verwenden möchten.

Für CORS Ihre Server mit den Header auf eine OPTIONS Anfrage reagieren muss:

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

ich bin kein Experte Schienen, aber Sie müssen wahrscheinlich etwas tun mit dem Edelstein rack-cors siehe here oder here.

Sie könnten das tun, indem Sie das Überschreiben der ajax Haken in der RESTAdapter etwa so:

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

Um CORS zu verwenden, muss ich nur etwas wie 'Access-Control-Allow-Origin: * 'zum Antwortkopf des Servers hinzufügen? – xamenrax

+0

ja hier: http://en.wikipedia.org/wiki/Cross-origin_resource_sharing und hier: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS Es gibt einige andere Überschriften, die Sie steuern können Genauer gesagt, was erlaubt ist. – albertjan

+0

Überprüfen Sie bitte das Update. – xamenrax

1

Ich habe eine einfache Arbeit um in Rails (das bisher für mich funktioniert.) Es unsauber ist wie es ist, aber kann leicht mit Logik in den Controllern verschärft werden.

In routes.rb:

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

die einfach Status OK einem OPTIONS Anfrage zurückgibt.

def allow 
    head :ok 
end 

Und dann in application_controller.rb setzen die Cross-Origin Resource Sharing (CORS) Header für jede Anforderung:

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 
+0

Aber es war nichts falsch mit meinen Headern, nur Rails gab mir HTML zurück, während ich Json brauchte. Also Workaround sagt nur direkt zu Rails, dass Sie Json - Adapter buildURL Methode erweitern möchten. Entschuldigung für mein Englisch. – xamenrax

1

Wenn Sie schauen, JSONP zu verwenden, es ist viel einfacher, die privaten ajaxOptions Funktion stattdessen außer Kraft zu setzen Verwenden von jQuery und Überschreiben der ajax Methode. Die Ember-Pipeline enthält die Entfernung der jQuery-Abhängigkeit. So tun Sie stattdessen:

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

Es wäre zu erstellen, wenn die Ember Kernteam eine öffentliche Methode aussetzen könnte offiziell dies zu unterstützen (statt ein eigenes api von Hacking).

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