2013-07-17 21 views

risposta

23

Si possono avere i risultati di una richiesta AJAX che ha intestazioni personalizzate essere impostati come il contenuto di un iframe in questo modo:

$.ajax({ 
    type: "GET", 
    url: "https://app.icontact.com/icp/a/", 
    contentType: "application/json", 
    beforeSend: function(xhr, settings){ 
      xhr.setRequestHeader("some_custom_header", "foo");}, 
    success: function(data){ 
     $("#output_iframe_id").attr('src',"data:text/html;charset=utf-8," + escape(data)) 
    } 
}); 

Ciò presuppone l'iframe è indicando una src dominio croce. È più semplice se tutto è nello stesso dominio.

Modifica: Forse prova questa variante.

$.ajax({ 
    type: "GET", 
    url: "https://app.icontact.com/icp/a/", 
    contentType: "application/json", 
    beforeSend: function(xhr, settings){ 
      xhr.setRequestHeader("some_custom_header", "foo");}, 
    success: function(data){ 
     $("#output_iframe_id").attr('src',"/") 
     $("#output_iframe_id").contents().find('html').html(data); 
    } 
}); 
+1

Grazie mille! A proposito, qual è la differenza se si trova nello stesso dominio? – dave

+1

Non funziona per IE: -S. In Chrome e Firefox ha funzionato, ma le regole CSS e gli script da file esterno (a cui si fa riferimento all'interno del frame) non vengono applicati. – dave

+0

dai uno scatto forse –

4

Il seguente codice funziona. È una modifica di code provided by Matthew Graves, modificata per utilizzare l'attributo srcdoc per risolvere il problema dei riferimenti CSS e JavaScript non eseguiti. Sfortunatamente, funziona solo in Chrome.

$.ajax({ 
     type: "GET", 
     url: "https://app.icontact.com/icp/a/", 
     contentType: "application/json", 
     beforeSend: function(xhr, settings){ 
       xhr.setRequestHeader("some_custom_header", "foo");}, 
     success: function(data){ 
      $("#output_iframe_id").attr('srcdoc',data) 
     } 
    }); 

Edit: Infine, ho risolto il problema del blocca gli script cross-browser, da loro riassegnazione al iframe sulla funzione document.ready:

$(document).ready(function() { 
    var doc = $(document); 
    if (frames.length > 0) { 
     doc = frames[0].document; 
     $(doc).find('script').each(function() { 
      var script = document.createElement("script"); 
      if ($(this).attr("type") != null) script.type = $(this).attr("type"); 
      if ($(this).attr("src") != null) script.src = $(this).attr("src"); 
      script.text = $(this).html(); 
      $(doc).find('head')[0].appendChild(script); 
      $(this).remove(); 
     }); 
    } 
}); 
4

ho finito per andare con l'approccio proposto dalle altre risposte qui, che utilizza ajax per ottenere la stringa html e quindi imposta direttamente il contenuto dello iFrame.

Tuttavia, ho utilizzato l'approccio pubblicato in questo answer per impostare effettivamente il contenuto dello iFrame, in quanto ho trovato che funzionava bene su più piattaforme con quasi tutti i dispositivi che potevo scavare.

Provato - successo:

  • Chrome 54 (desktop)^
  • Firefox 49 (desktop)^
  • IE 11 (desktop)^
  • IE 10 (desktop) in modalità di emulazione^
  • Safari/Chrome su iOS 8 (ipad)
  • Chrome su Android 6 (telefono Nexus)
  • Edg e il Lumia 950 (Win 10 Telefono)

^confermato che css linked e js nel contenuto vengono eseguiti correttamente (gli altri non testati)

Provato - senza successo:

  • IE 9 (desktop) in modalità di emulazione
  • Safari/Chrome su iOS 7 (iPhone)

Così li mettere insieme dà qualcosa di simile (Nota: Il havn't in realtà eseguire questo codice esatto):

$.ajax({ 
    type: "GET", 
    url: "https://yourdomain.com/gethtml", 
    beforeSend: function(xhr) { 
     xhr.setRequestHeader("yourheader", "value"); 
    }, 
    success: function(data) { 
     var iframeDoc = document.querySelector('#myiframe').contentWindow.document; 
     iframeDoc.open('text/html', 'replace'); 
     iframeDoc.write(data); 
     iframeDoc.close(); 
    } 
}); 

Ecco un esempio di impostazione delle iFrame contenuti in this JS Bin

Edit: ecco la parte html

<iframe id="myiframe" src="about:blank"></iframe> 

Edit 2:

La soluzione sopra ap le pere non funzioneranno più in Firefox (50.1.0) per qualche motivo sconosciuto. Utilizzando la soluzione in questo answer Ora ho cambiato per il codice per l'esempio seguente, che sembra anche essere più robusto:

$.ajax({ 
    type: "GET", 
    url: "https://yourdomain.com/gethtml", 
    beforeSend: function(xhr) { 
     xhr.setRequestHeader("yourheader", "value"); 
    }, 
    success: function(data) { 
     var iframe = document.getElementById('myiframe'); 
     iframe.contentWindow.contents = data; 
     iframe.src = 'javascript:window["contents"]'; 
    } 
}); 
+1

sfortunatamente se carichi alcuni contenuti utilizzando percorsi in-app relativi, probabilmente dovrai affrontare dei problemi. Provato con angular2 e ha problemi di routing 'route not found' ... Non ho ancora trovato nessuna risposta. – eatmypants

+0

@eatmypants Non sei sicuro di quello che stai incontrando - Non ho giocato con angular2, ma lo sto usando in angular1. Poiché la chiamata al server è ajax, dovresti essere in grado di risolvere i tuoi URL in qualunque modo tu faccia per qualsiasi altra chiamata ajax. Stai modificando il 'src' di' iFrame' forse? Lo lascio come 'about: blank'. –

5

Invece di utilizzare un dato URI, o impostando il contenuto in una stringa, è possibile utilizzare URL.createObjectURL() e impostarlo come src dell'iframe.

var xhr = new XMLHttpRequest(); 

xhr.open('GET', 'some.pdf'); 
xhr.onreadystatechange = handler; 
xhr.responseType = 'blob'; 
xhr.setRequestHeader('Authorization', 'Bearer ' + token); 
xhr.send(); 

function handler() { 
    if (this.readyState === this.DONE) { 
    if (this.status === 200) { 
     // this.response is a Blob, because we set responseType above 
     var data_url = URL.createObjectURL(this.response); 
     document.querySelector('#output-frame-id').src = data_url; 
    } else { 
     console.error('no pdf :('); 
    } 
    } 
} 

Gli URL degli oggetti sono piuttosto interessanti. Sono nella forma blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170. Puoi effettivamente aprirli in una nuova scheda e vedere la risposta, e vengono scartati quando il contesto che li ha creati è chiuso.

Ecco un esempio completo: https://github.com/courajs/pdf-poc

+0

Sembra la migliore risposta, se l'oggetto URL è disponibile. In caso contrario, eseguire il downgrade alla risposta accettata. –

Problemi correlati