2013-02-12 25 views
11

Chúc mừng! Tôi có cửa hàng ember dữ liệu:Trình phục hồi dữ liệu ember.js không tải json

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

Và router:

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

tôi nhận JSON từ máy chủ từ xa:

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

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

Nhưng khi tôi cố gắng return TravelClient.Tour.find() nó không thành công với:

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. 

CNTT có vẻ như RESTAdapter không biết, rằng nó phải nhận được JSON hay cái gì?

UPDATE:

Trong bộ điều khiển ứng dụng trên các đường ray server-side:

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

Nhưng nó vẫn còn:

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

Và có vẻ như RESTAdapter cố gắng để tải các tour du lịch tài nguyên, không phải tours.json:

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

LÀM VIỆC GIẢI PHÁP

Mở rộng 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"; 
    } 
}) 

và đáp ứng với một OPTIONS yêu cầu với tiêu đề đúng

+0

tiêu đề bạn thiết lập được trả về với 'GET' yêu cầu bạn cần phải trả lại chúng với một' OPTIONS' yêu cầu – albertjan

+0

CORS Kệ đá quý đã làm các trick, cảm ơn. Tôi nghĩ rằng nó làm tất cả những thứ với OPTIONS yêu cầu chỉ "ra khỏi hộp". – xamenrax

+0

Heres liên kết cho khách truy cập tiếp theo https://github.com/cyu/rack-cors ftw – genkilabs

Trả lời

10

Các RESTAdapter hy vọng JSON đó không phải là vấn đề nhưng trang và json không nằm trên cùng một miền, đây là vấn đề bảo mật. Bạn có thể giải quyết vấn đề này bằng cách sử dụng một trong hai giải pháp có tên dưới đây.

Bạn đang chạy vào same origin policy bạn nên sử dụng JSONP hoặc CORS. Sửa chữa nhanh nhất có thể là để nói với dữ liệu ember mà bạn muốn sử dụng JSONP.

Đối CORS máy chủ của bạn cần phải đáp ứng một yêu cầu OPTIONS với tiêu đề:

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

tôi không có chuyên môn ray nhưng có thể bạn sẽ cần phải làm một cái gì đó với đá quý rack-cors xem here hoặc here.

Bạn có thể làm điều đó bằng cách ghi đè móc ajax trong RESTAdapter như vậy:

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

Để sử dụng CORS, tôi chỉ cần thêm smth như 'Access-Control-Allow-Origin: *' vào tiêu đề phản hồi của máy chủ? – xamenrax

+0

có xem tại đây: http://en.wikipedia.org/wiki/Cross-origin_resource_sharing và tại đây: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS Có một số tiêu đề khác mà bạn có thể kiểm soát cụ thể hơn những gì được cho phép. – albertjan

+0

Kiểm tra cập nhật, vui lòng. – xamenrax

1

Tôi có một công việc đơn giản xung quanh trong Rails (có nghĩa là làm việc cho tôi cho đến nay.) Đó là lộn xộn như là, nhưng có thể dễ dàng được thắt chặt với logic trong bộ điều khiển.

Trong routes.rb:

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

Mà chỉ đơn giản là trả về tình trạng OK với bất kỳ yêu cầu OPTIONS.

def allow 
    head :ok 
end 

Và sau đó trong application_controller.rb thiết lập chia sẻ tài nguyên giữa các gốc (CORS) tiêu đề cho mọi yêu cầu:

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

Nhưng không có gì sai với tiêu đề của tôi, chỉ Rails đã cho tôi trở lại html, trong khi tôi đã cần json. Vì vậy, workaround chỉ là nói với Rails trực tiếp mà bạn muốn json - mở rộng adapter của phương pháp buildURL. Xin lỗi vì tiếng Anh của tôi. – xamenrax

1

Nếu bạn đang muốn sử dụng JSONP nó dễ dàng hơn để ghi đè các tin ajaxOptions chức năng thay vì sử dụng jQuery và ghi đè phương thức ajax. Ember của đường ống bao gồm việc loại bỏ sự phụ thuộc của jQuery. Vì vậy, làm điều này thay vì:

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

Nó sẽ tạo ra nếu đội ngũ nòng cốt Ember có thể phơi bày một phương pháp nào để hỗ trợ chính thức này (thay vì hack một api tư nhân).

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

Các vấn đề liên quan