I understand that you can set HTTP request headers very easily when making AJAX calls in JavaScript.
However is it also possible to set custom HTTP request headers w
No, you can't. However you could set the iframe
source to some kind of preload script, which uses AJAX to fetch the actual page with all the headers you want.
As @FellowMD answer is not working on modern browsers due to the depreciation of createObjectURL, I used the same approach but using iframe srcDoc attribute.
Please find below a React example (I know it is overkill):
import React, {useEffect, useState} from 'react';
function App() {
const [content, setContent] = useState('');
useEffect(() => {
// Fetch the content using the method of your choice
const fetchedContent = '<h1>Some HTML</h1>';
setContent(fetchedContent);
}, []);
return (
<div className="App">
<iframe sandbox id="inlineFrameExample"
title="Inline Frame Example"
width="300"
height="200"
srcDoc={content}>
</iframe>
</div>
);
}
export default App;
Srcdoc is now supported on most browsers. It seems that Edge was a bit late to implement it: https://caniuse.com/#feat=iframe-srcdoc
You can make the request in javascript, setting any headers you'd like. Then you can URL.createObjectURL(), to get something suitable for the src
of the iframe.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'page.html');
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 :(');
}
}
}
The MIME type of the response is preserved. So if you get an html response, the html will show in the iframe. If you requested a pdf, the browser pdf viewer will kick in for the iframe.
If this is part of a long-lived client-side app, you may want to use URL.revokeObjectURL() to avoid memory leaks.
The object URLs are also pretty interesting. They're of the form blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170
. You can actually open them in a new tab and see the response, and they're discarded when the context that created them is closed.
Here's a full example: https://github.com/courajs/pdf-poc
It turns out that URL.createObjectURL() is deprecated in Chrome 71
(see https://developers.google.com/web/updates/2018/10/chrome-71-deps-rems)
Building on @Niet the dark Absol and @FellowMD's excellent answers, here's how to load a file into an iframe, if you need to pass in authentication headers. (You can't just set the src attribute to the URL):
$scope.load() {
var iframe = #angular.element("#reportViewer");
var url = "http://your.url.com/path/etc";
var token = "your-long-auth-token";
var headers = [['Authorization', 'Bearer ' + token]];
$scope.populateIframe(iframe, url, headers);
}
$scope.populateIframe = function (iframe, url, headers) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'document';
headers.forEach(function (header) {
xhr.setRequestHeader(header[0], header[1]);
});
xhr.send();
function handler() {
if (this.readyState === this.DONE) {
if (this.status === 200) {
var content = iframe[0].contentWindow ||
iframe[0].contentDocument.document ||
iframe[0].contentDocument;
content.document.open();
content.document.write(this.response.documentElement.innerHTML);
content.document.close();
} else {
iframe.attr('srcdoc', '<html><head></head><body>Error loading page.</body></html>');
}
}
}
}
and shoutout to courajs: https://github.com/courajs/pdf-poc/blob/master/script.js