Existe-t-il un moyen d'ajouter un en-tête http personnalisé dans la demande effectuée par un <iframe>
lors du changement de source (src) en utilisant javascript?
Vous pouvez faire en sorte que les résultats d'une demande ajax contenant des en-têtes personnalisés soient définis comme le contenu d'une iframe:
$.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))
}
});
Cela suppose que l'iframe pointe vers un src interdomaine. C'est plus simple si tout est sur le même domaine.
Edit: Essayez peut-être cette 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);
}
});
Plutôt que d'utiliser un URI de données ou de définir le contenu sur une chaîne, vous pouvez utiliser URL.createObjectURL()
, et le définir comme src
de l'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 :(');
}
}
}
Les URL des objets sont assez intéressantes. Ils sont de la forme blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170
. Vous pouvez réellement les ouvrir dans un nouvel onglet et voir la réponse, et ils sont supprimés lorsque le contexte qui les a créés est fermé.
Voici un exemple complet: https://github.com/courajs/pdf-poc
Le code suivant fonctionne. Il s'agit d'une modification du code fourni par Matthew Graves , modifié pour utiliser l'attribut srcdoc
pour résoudre le problème des références CSS et JavaScript non exécutées. Malheureusement, cela ne fonctionne que dans 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 : Enfin, j'ai résolu le problème des blocs de scripts cross-browser, en les réaffectant à la fonction iframe on 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();
});
}
});
J'ai fini par suivre l'approche proposée par les autres réponses ici, qui utilise ajax pour obtenir la chaîne html, puis définit directement le contenu du iFrame
.
Cependant, j'ai utilisé l'approche publiée dans ce réponse pour définir le contenu de iFrame
, car j'ai trouvé que cela fonctionnait bien sur plusieurs plates-formes avec presque tous les appareils que je pouvais creuser.
Testé - réussi:
^ a confirmé que les css et js liés dans le contenu fonctionnent correctement (d'autres non testés)
Testé - échoué:
Donc, les assembler donne quelque chose comme ça (Remarque: je n'ai pas réellement exécuté ce code exact):
$.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();
}
});
Voici un exemple de configuration du contenu de iFrame
dans ce JS Bin
Edit: Voici la partie html
<iframe id="myiframe" src="about:blank"></iframe>
Édition 2:
La solution ci-dessus semble ne plus fonctionner dans Firefox (50.1.0) pour une raison inconnue. En utilisant la solution dans cette réponse J'ai maintenant changé de code pour l'exemple ci-dessous, qui semble également être plus robuste:
$.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"]';
}
});