2014-02-14 12 views
13

Es scheint, dass jetzt in Rails 4 mit Asset-Pipeline und der Ritzel-Schienen-Edelstein, wenn Bilder verarbeitet werden, ihr Dateiname ist mit einem MD5-Fingerabdruck wie CSS und Javascript angehängt. Während dies sinnvoll ist, weil md5 fingerprints are awesome, macht es zunehmend schwieriger auf das Bild von Javascript zugreifen. In Rails 3.2 konnte ich mit /assets/image_name.jpg auf das Image zugreifen und es würde richtig funktionieren, aber in Rails 4 existiert dieses Asset nicht, es existiert nur mit dem md5-Fingerprint im Namen.Zugriff auf Bilder auf der Produktion, von Javascript, in Rails 4

Ich weiß, dass Schienen bietet Helfer, um das Bild über erb <%= asset-url("image_name.jpg") %> zugreifen, aber das ist weniger ideal in Javascript, weil ich nicht erb in meinem js. Es gibt viele Möglichkeiten, dies mit Datenattributen zu umgehen, die in den Views dienen oder ein Skript-Tag in meiner Ansicht verwenden und einige Globals setzen, aber ich suche nach einer netten Lösung für dieses Problem, falls es existiert.

Jede Hilfe wird geschätzt, danke.

Antwort

0

Warum müssen Sie die Asset-Pipeline für Bilder verwenden? Ich bekomme das Hashing-Verhalten. Normalerweise werden die Assets jedoch vorverarbeitet. Wenn Sie die Bilder wie in alten Zeiten in die öffentliche Hierarchie einfügen, erhalten Sie ein normales Pfad-Routing.

Hier ist ein Zitat aus dem Asset Pipleline Leitfaden, die ich denke, könnte germane sein. "Assets können immer noch in der öffentlichen Hierarchie platziert werden. Alle öffentlich zugänglichen Assets werden von der Anwendung oder dem Webserver als statische Dateien bereitgestellt. Sie sollten App/Assets für Dateien verwenden, die vor der Verarbeitung eine Vorverarbeitung durchlaufen müssen."

+0

Was passiert, wenn ich die Abnahme von Fingerabdrücken von Bild-Assets nutzen möchten Cache brechen auf Updates? Wie kann ich auf ein Fingerabdruckbild von einer Javascript-Variable zugreifen? – Micah

+0

Ich bin auf der Suche nach dem gleichen, und ich habe das gefunden. Es macht, wonach Sie suchen. https://github.com/johnnypez/assets_js. –

0

Leider glaube ich, dass Sie stecken entweder eine ERB-Erweiterung zu Ihrem JS hinzufügen und die Asset-Helfer verwenden, oder nicht die Asset-Pipeline für die Assets verwenden.

0

Wenn Sie sagen "Ich benutze nicht erb in meinem js", meinst du, du willst nicht, oder einfach, dass du nicht bist? Weil du es kannst!

var src = "<%= asset_url('photo.jpg') %>"; 
+0

Nicht wirklich eine gute Option, wenn Sie mit einer Menge von Bildern zu tun haben und die SRC dynamisch (in JS) bevölkern - anstatt hart zu codieren, wie Sie es sind. –

1

Eine weitere Option zu prüfen (obwohl ich es nicht empfehlen würde) sind:

Wenn Sie die entsprechenden JS Dateien mit der Endung umbenennen .js.erb dann können Sie die asset_url Helfer in diesen Dateien wie so verwenden Verwenden Sie eine benutzerdefinierte Route in Ihrem Anwendungscontroller, um den Assetpfad für Sie im Controller abzurufen, und geben Sie die URL entweder mit dem Hash md5 an das Asset zurück oder geben Sie nur die rohen Binärdaten des Assets zurück Anwendung).

Zum Beispiel machen Sie eine AJAX-Anforderung zu http://yourapp.com/images?file=my_image.jpg

Dann in Ihrem Controller erhalten Sie Ihre Aktion-Methode würde wie folgt aussehen:

def images 
    ActionController::Base.helpers.asset_url(params[:file]) 
end 

Dies würde dann den URL-Pfad zum Asset zurückzukehren. Der Nachteil dieser Methode besteht darin, dass Sie zwei Anforderungen auf der JS-Seite stellen müssen. Der erste, der den Pfad zum Asset erhält, und der zweite, der diesen Asset mit dem zurückgegebenen Pfad tatsächlich lädt.

Um dies auf eine Anforderung zu reduzieren, können Sie die Anwendung das Bild aus dem Dateisystem lesen lassen und die richtigen Header zurückgeben, damit der Browser denkt, dass ein Bild zurückgegeben wird und daher die URL zur Verfügung stellt. Dies wäre jedoch viel mehr Arbeit für die Anwendung und viel mehr unnötige Festplatten IO auf Ihrem Server.

Es nehmen können zwei Anträge für jedes Bild auf dem Client zu erreichen, was Sie wollen, aber Sie haben irgendwo zu opfern ...

+0

Dies könnte mit "einer Anfrage auf der JS-Seite" funktionieren, indem 'redirect_to' verwendet wird, um die Browser-Anfrage einfach auf das korrekte Asset umzuleiten. Während es technisch immer noch zwei Anfragen gibt, müssten Sie keinen weiteren JS-Code schreiben, um damit umzugehen. Sie würden tun: 'redirect_to ActionController :: Base.helpers.asset_url (params [: Datei])' ... aber Bypass der Asset-Pipeline wird Probleme (Caching, etc.), so dass es definitiv nicht für die tatsächliche Produktion empfohlen wird benutzen. Einmalige und einfache Let-me-sehen-das-Ding-Art von Tests in Prod sollte aber in Ordnung sein. –

+0

Ja @KarlWilbur hat recht, redirect_to scheint eine viel sauberere Lösung zu sein. –

Verwandte Themen