Domanda

Su un sito Web basato su PHP, desidero inviare agli utenti un pacchetto di download dopo aver compilato un breve modulo.Il download avviato dal sito dovrebbe essere simile a siti come download.com, che dicono "il download inizierà tra un attimo".

Un paio di possibili approcci Conosco e compatibilità del browser (basato su un rapido test):

1) Fai un window.open puntando al nuovo file.

- FireFox 3 blocks this.  
 - IE6 blocks this.  
 - IE7 blocks this.

2) Crea un iframe che punta al nuovo file.

- FireFox 3 seems to think this is OK. (Maybe it's because I already accepted it once?)  
 - IE6 blocks this.  
 - IE7 blocks this.

How can I do this so that at least these three browsers will not object? 

Bonus:esiste un metodo che non richiede istruzioni condizionali del browser?

(Credo che download.com utilizzi entrambi i metodi in modo condizionale, ma non riesco a far funzionare nessuno dei due.)

Risposte e chiarimenti:

Q: "Why not point the current window to the file?"  
A: That might work, but in this particular case, I want to show them some other content while their download starts - for example, "would you like to donate to this project?"

AGGIORNAMENTO:Ho abbandonato questo approccio.Vedi la mia risposta qui sotto per i motivi.

È stato utile?

Soluzione

Puoi anche eseguire un meta aggiornamento, supportato dalla maggior parte dei browser.Download.com ne inserisce uno in un tag noscript.

<meta http-equiv="refresh" content="5;url=/download.php?doc=123.zip"/>

Altri suggerimenti

Aggiornamento:Ho deciso di abbandonare questo approccio e presentare invece all'utente semplicemente un collegamento al file vero e proprio.Il mio ragionamento è questo:

I miei tentativi iniziali di download avviato dal server sono stati bloccati dal browser.Questo mi ha fatto pensare:"il browser è corretto.Come fa Esso sai che si tratta di un download legittimo?Esso Dovrebbe bloccare un download che non è stato ovviamente avviato dall'utente."

Qualsiasi metodo che posso utilizzare per un download avviato dal server potrebbe Anche essere utilizzato da qualcuno che desidera inviare malware.Pertanto, i download dovrebbero avvenire solo quando l'utente richiede specificamente il file facendo clic su un relativo collegamento.

Sei libero di non essere d'accordo e, se desideri comunque avviare un download, speriamo che questo thread ti aiuti a farlo.

Di solito ho solo uno script PHP che invia il file direttamente al browser con il tipo di contenuto appropriato

if(file_exists($filename)) {
    header("Pragma:  public");
    header("Expires:  0");
    header("Cache-Control:  must-revalidate, pre-check=0");
    header("Cache-Control:  private", false);
    header("Content-Type:  " . $content-type);
    header("Content-Disposition:  attachment; filename=\"" . basename($filename) . "\";" );
    header("Content-Transfer-Encoding:  binary");
    header("Content-Length:  " . filesize($filename));

    readfile("$filename");
}else{
    print "ERROR:  the file " . basename($filename) . " could not be downloaded because it did not exist.";
}

L'unico svantaggio è che, poiché imposta l'intestazione HTTP, deve essere chiamato prima di avere qualsiasi altro output.

Ma puoi avere un collegamento alla pagina di download di PHP e questo farà sì che il browser apra una casella di download senza rovinare il contenuto della pagina corrente.

Un problema è che potresti riscontrare problemi con IE (versione 6 in particolare) se le intestazioni non sono impostate "correttamente".

Assicurati di impostare il tipo di contenuto corretto, ma valuta anche la possibilità di impostare le opzioni Cache per IE (almeno) su permettere memorizzazione nella cache.Se il file è uno di quelli che l'utente può aprire anziché salvare (ad es.un documento MS Word) le prime versioni di IE necessitano di memorizzare nella cache il file, poiché trasmettono la richiesta "aperta" all'app applicabile, indicando il file che è stato scaricato nella cache.

C'è anche un problema correlato, se la cache dell'utente IE6 è piena, non salverà correttamente il file (quindi quando l'app applicabile riesce ad aprirlo, si lamenterà che il file è corrotto.

Potresti anche voler disattivare qualsiasi azione gzip anche sui download (per IE)

Entrambi IE6/IE7 hanno problemi con download di grandi dimensioni (ad es.4.x Gigs...) non è uno scenario probabile poiché IE non ha nemmeno un download manager, ma è qualcosa di cui essere consapevoli.

Infine, IE6 a volte non gestisce bene un "push" di download se è stato avviato all'interno di un iframe nidificato.Non sono esattamente sicuro di cosa scateni il problema, ma trovo che sia più semplice con IE6 evitare questo scenario.

Hoi!

@Nathan:Ho deciso di fare esattamente questo:Chiedi al mio "getfile.php" di caricare tutte le cose necessarie e poi fai a

header("Location: ./$path/$filename");

per consentire al browser stesso di fare direttamente tutto ciò che ritiene corretto fare con il file.Con me funziona bene anche in Opera.

Ma questo sarà un problema negli ambienti in cui non è consentito l'accesso diretto ai file, in tal caso dovrai trovare un modo diverso!(Grazie a Discordia i miei file sono PDF pubblici!)

I migliori saluti, Basty

Che ne dici di cambiare la posizione in modo che punti al nuovo file?(per esempio.modificando window.location)

Ho sempre creato un iframe che punta al file.

<iframe src="/download.exe" frameborder="0" height="0" width="0"><a href="/download.exe">Click here to download.</a></iframe>

Per quanto riguarda il non indirizzare la finestra corrente al download.Nella mia esperienza puoi ancora mostrare la tua pagina "per favore fai una donazione", poiché i download (a condizione che inviino le intestazioni corrette) in realtà non aggiornano la finestra del browser.Lo faccio per le esportazioni CSV su uno dei miei siti e, per quanto riguarda l'utente, viene semplicemente visualizzata una finestra di file sicura.Quindi consiglierei un semplice meta-reindirizzamento come ha mostrato Soldarnal.

Giusto per riassumere, hai 2 obiettivi:

  1. avviare il processo di download
  2. mostra all'utente una pagina con le opzioni di donazione

Per raggiungere questo obiettivo farei quanto segue:

Quando il tuo utente invia il modulo, ottiene la pagina risultante con le opzioni di donazione e un testo che dice che il suo download inizierà tra 5 secondi.E nella sezione head di questa pagina inserisci il codice META come ha detto Soldarnal:<meta http-equiv="refresh" content="5;url=/download.php?doc=123.zip>

E questo è tutto.

<a href="normaldownload.zip" onclick="use_dhtml_or_ajax_to_display_page()">

La pagina corrente non viene influenzata se il download viene salvato.Assicurati solo che il download non si apra nella stessa finestra (tipo MIME corretto o Content-Disposition) e sarai in grado di mostrare qualsiasi cosa.

Vedi la risposta più completa

Puoi utilizzare Javascript/jQuery per avviare il download.Ecco un esempio: puoi eliminare la richiesta Ajax e utilizzare semplicemente il blocco setTimeout().

$("btnDownloadCSV").on('click', function() {
    $.ajax({
        url: "php_backend/get_download_url",
        type: 'post',
        contentType: "application/x-www-form-urlencoded",
        data: {somedata: "somedata"},
        success: function(data) {
            // If iFrame already exists, remove it.
            if($("[id^='iframeTempCSV_"]).length) { 
                $("[id^='iframeTempCSV_"]).remove();
            }
            setTimeout(function() {
                //  If I'm creating an iframe with the same id, it will permit download only the first time.
                // So randHashId appended to ID to trick the browser.
                var randHashId = Math.random().toString(36).substr(2);
                // Create a fresh iFrame for auto-downloading CSV
                $('<iframe id="iframeTempCSV_'+randHashId+'" style="display:none;" src="'+data.filepath+'"></iframe>').appendTo('body');
            }, 1000);
        },
        error: function(xhr, textStatus, errorThrown) {
           console.error("Error downloading...");
       }
    });
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top