2012-12-23 17 views
11

Ho uno script che i siti Web di terze parti utilizzano: /assets/script.js. Per ovvi motivi, non posso chiedere loro di cambiare il link ogni volta che eseguo il deploy per puntare all'ultima versione impronta digitale della sceneggiatura. Ho riscontrato alcuni problemi di memorizzazione nella cache in cui gli utenti vedono ancora le vecchie versioni di /script.js. Esistono modi per far sparire la cache direttamente per script.js anziché script-9dc5afea3571ba2a883a72b0da0bb623.js?Caching di script di terze parti in Rails 3.1

Ulteriori informazioni: Rails on Passenger + Nginx. Alla ricerca di modi per servire il file script.js invece se il file stampato con le dita e invalidare la cache su ogni distribuzione.

Ho pensato di aggiungere ETags in base alla revisione del git di distribuzione, ma non ho idea di come farlo. Nginx non ha un supporto ETags integrato. Esistono moduli di terze parti non supportati che eseguono questa operazione. Posso usare add_header Etag="something" per questo, ma come faccio ad aggiungere la versione git lì.

Altre idee e opzioni?

Grazie!

+2

C'è una soluzione comune per questo - /scripts.js? , ma in alcuni casi potrebbe essere un problema. – iced

+1

Per chiarire "male in alcuni casi" - non tutti i server/edge location/browser rispettano una stringa di query un invalidatore di cache. –

risposta

9

Se si dispone di uno script con un nome che fa parte dell'interfaccia pubblica, è necessario avviare la versione di questo script in modo esplicito e conservare le versioni precedenti per i client precedenti.

ad es. /assets/script.1.0.js, /assets/script.1.1.js etc

La parte fondamentale è che è necessario mantenere i vecchi in giro e il codice non cambia senza che il nome cambi esplicitamente. La pipeline di asset di Rails non può farlo per te, dal momento che di solito rimane aggiornata solo la versione più recente dello script.

Come con tutte le interfacce pubbliche, è necessario dedicare più tempo alla gestione di questo processo rispetto a uno script solo interno.

+0

Ciò significa che gli utenti dovranno modificare manualmente la versione dello script quando desiderano eseguire l'aggiornamento. Ho bisogno di un nome di file, 'script.js', che invalida la cache quando cambia (sulla distribuzione) – CamelCamelCamel

+0

Questo è corretto, ma significa anche che i tuoi utenti stanno usando la versione del tuo script con cui hanno provato. Ecco come, ad es. JQuery funziona. Se vuoi che funzioni come Google Analytics, dovrai disabilitare la memorizzazione nella cache e chiedere loro di ottenere il codice da te per ogni richiesta –

3

Si consiglia di utilizzare un ETag. Aggiungere un header ETag per la vostra risposta http://en.wikipedia.org/wiki/HTTP_ETag

Impostare l'ETag a un diverso, stringa univoca per ogni versione dello script. Ciò assicurerà che i browser ottengano una nuova versione dello script ogni volta che si distribuisce una nuova versione.

1

Seguendo il suggerimento di ETag, potresti trovare questa gemma utile: bust_rails_etags. Ti permette di impostare una chiave su ogni distribuzione che viene utilizzata nella generazione di ETag, in questo modo, i tuoi ETags cambieranno (e quindi lo script memorizzato nella cache sarà invalidato) ogni volta che la tua app viene distribuita. L'autore utilizza l'esempio dei numeri di rilascio di Heroku come chiave che cambia in ogni distribuzione.

1

Quello che sto usando per le attività di aggiornamento è:

  1. Incremento config.assets.version in config/application.rb come

    #Version of your assets, change this if you want to expire all your assets 
    config.assets.version = '1.1' 
    
  2. bundle exec rake assets:precompile RAILS_ENV=production RAILS_GROUPS=assets

  3. App riavvio, la cache server web vuoto se qualsiasi

1

Volete un URL un'attività non le impronte digitali per i siti web di terze parti . Ad esempio: assets/public_api.js

Ci sono stati plugin o gemme che hanno escluso le risorse specificate dalle impronte digitali. Tuttavia rails ha modificato il processo di pre-compilazione in modo da creare anche file non fingerprint. Quindi questo non è un problema. Maggiori informazioni here.

Come assicurarsi che i client stiano caricando lo script distribuito più recente, quando la risorsa non viene rilevata?

Vorrei suggerire la soluzione youTube uses to expose their API. Fondamentalmente tutte le risorse/public_api.js lo fanno, inietta un altro tag script nel dom. Quello iniettato carica il vero codice API. Ora i vostri beni/public_api.js diventa attività/public_api.js.erb e simile a questa:

var tag = document.createElement('script'); 
tag.src = "<%=asset_path('/assets/javascripts/acctual_api')%>"; 
var firstScriptTag = document.getElementsByTagName('script')[0]; 
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 

Si prega di notare come tag.src è impostato sul percorso corrente impronte digitali a/attività/javascript/acctual_api. In questo modo i tuoi utenti otterranno sempre l'ultimo script acctual_api compilato.

Come aggiornare l'ETAG per le risorse/public_api.js?

Suppongo che tu utilizzi Capistrano o una soluzione di distribuzione basata su ricette simili. Forse potresti aggiungere una fase di distribuzione che aggiorna il file di configurazione del server prima del suo riavvio. Si deve solo aggiornare:

add_header Etag="update_me_on_deploy" 

Si prega di notare che si dovrebbe comunque utilizzare di versione (attività/public_api.0.js) script pubblici anche con questo approccio.

1

Se si utilizza Capistrano, è possibile scrivere un'attività che copia lo script da Pubblico/risorse in un'altra directory all'interno di Pubblico (ovvero Pubblico/script) dopo che le risorse sono state precompilate.

1

Ebbene si può rimuovere l'impronta digitale del file:

asset_path('script.js', :digest => false) 

Speranza che aiuta

oppure è possibile utilizzare questo gioiello se si desidera: https://github.com/spohlenz/digestion

Ma: The Rails patrimoniale gasdotto ora compila file di asset con e senza digest.

Quindi dopo aver generato le risorse di solito hai ottenuto script.js? Xxxxx e script.js nella cartella public/assets.

Problemi correlati