4 Stimmen

Rails, REST Architektur und HTML 5: Cross-Domain Anfragen mit Pre-Flight Anfragen

Bei der Arbeit an einem Projekt, um unsere Website HTML5-freundlich zu machen, waren wir gespannt darauf, die neue Methode für Cross-Domain-Anfragen zu übernehmen (kein Posten mehr durch versteckte IFrames!!!). Mit der Access Control-Spezifikation begannen wir damit, einige Tests einzurichten, um das Verhalten verschiedener Browser zu überprüfen.

Die aktuelle Rails-RESTful-Architektur basiert auf den vier HTTP-Verben: GET, POST, PUT, DELETE. In der Access Control-Spezifikation wird jedoch festgelegt, dass nicht einfache Methoden (PUT, DELETE) eine Vorfahrtsanfrage unter Verwendung des HTTP-Verbs OPTIONS erfordern. Darüber hinaus haben wir bei Tests festgestellt, dass Firefox 3.5.8 auch Vorfahrtsanfragen für POST durchführt.

Meine Frage lautet: Ist jemand sich eines Projekts für das Rails-Framework bewusst, das sich mit dem Problem befasst? Falls nicht, gibt es Meinungen zur besten Strategie, um die OPTIONS-Methode zu unterstützen, da sie die Routen für alle POST-, PUT- und DELETE-Methoden unterstützen muss?

9voto

Calvin Punkte 462

Ich habe vor ein paar Tagen eine Gem veröffentlicht, das die CORS-Unterstützung über ein Rack-Middleware implementiert:

http://github.com/cyu/rack-cors

Was vorausgehende CORS-Anfragen betrifft, konnte ich in Chrome keine vorausgehenden Anfragen zum Laufen bringen (obwohl einfache CORS-Anfragen gut funktionieren). Die Suche im Internet legt nahe, dass dies möglicherweise nicht unterstützt wird. Ich habe Fragen im Chrome-Forum zu diesem Thema gestellt, aber noch keine Antwort erhalten.

3voto

Saurabh Wadhwa Punkte 1173

Dies stammt aus der Spine.js-Dokumentation

CORs Rails Integration

Lassen Sie uns eine COR-Methode erstellen, die einige der Anfrage-Zugriffssteuerungsheader zur Antwort der Anfrage hinzufügt.

Fügen Sie Folgendes zu app/application_controller.rb hinzu:

before_filter :cor

def cor
  headers["Access-Control-Allow-Origin"]  = "js-app-origin.com"
  headers["Access-Control-Allow-Methods"] = %w{GET POST PUT DELETE}.join(",")
  headers["Access-Control-Allow-Headers"] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(",")
  head(:ok) if request.request_method == "OPTIONS"
end

Auch wenn Access-Control-Allow-Origin ein Platzhalter akzeptiert, empfehle ich dringend, ihn nicht zu verwenden, da dies Ihre App für alle Arten von CSRF-Angriffen öffnet. Die Verwendung einer Whitelist ist viel besser und sicherer.

Der Abschnitt Access-Control-Allow-Headers ist wichtig, insbesondere der X-Requested-With-Header. Rails mag es nicht, wenn Sie Ajax-Anfragen ohne diesen Header senden, und ignoriert den Accept-Header der Anfrage, der HTML zurückgibt, obwohl er stattdessen JSON zurückgeben sollte.

Es ist erwähnenswert, dass jQuery diesen Header standardmäßig nicht zu Cross-Domain-Anfragen hinzufügt. Dies ist ein Problem, das Spine intern löst, aber wenn Sie für CORs einfach jQuery verwenden, müssen Sie den Header manuell spezifizieren.

jQuery.ajaxSetup({
  headers: {"X-Requested-With": "XMLHttpRequest"}
});

Einige Browser senden zuerst eine OPTIONS-Anfrage an den Server, um sicherzustellen, dass die richtigen Zugriffsheader festgelegt sind. Sie müssen dies in Rails abfangen und einen 200-Status mit den richtigen Headern zurückgeben. Fügen Sie dazu folgendes zur Datei config/routes.rb Ihrer Anwendung hinzu:

match '*all' => 'application#cor', :constraints => {:method => 'OPTIONS'}

Das war's, Sie sind bereit für Cross-Origin-Anfragen mit Spine!

0voto

coolaj86 Punkte 69032

Ich habe Rails gehackt, um die Options-Methode zu unterstützen. Ich habe dies in der Rails-Liste gepostet, aber es hat es nie über die Liste geschafft.

GitHub Gist: Rails XHR2 / CORS / OPTIONS support

ctrl+f, um die Zeilen zu finden, die #Options enthalten - das sind die einzigen, die ich geändert habe.

Und hier ist eine Beispielimplementierung | und eine andere

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X