I am trying to load a PDF as a blob in JavaScript from the backend, but receive Failed to execute 'createObjectURL' on 'URL': Overload resolution failed
. I'm not really sure where to go from here. I've looked at some of the other posts but none seem to deal with PDF, only audio.
The docs for createObjectURL
say: "The new object URL represents the specified File object or Blob object", so I'm not sure what I'm doing wrong. (https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL)
From my backend, I set: Content-type: application/octet-stream
then expect to be able to set the iFrame source, but it's not working.
I can verify that the blob data is in fact being returned from the backend.
This is the JS code that uses the blob.
iframe.src = URL.createObjectURL(data);
EDIT 1:
I'm being asked to edit my question with why the suggested prior post doesn't solve my issue. Here's a copy/paste from my comments below:
I did see that post already and the accepted answer says: "Consider avoiding createObjectURL() method, while browsers are disabling support for it. Just attach MediaStream object directly to the srcObject property of HTMLMediaElement e.g. element." I'm not an expert with JavaScript but I don't think MediaStream will work.
EDIT 2:
Thanks to David Caldwell, in his comment he mentioned "src/srcObject"which made me look a little closer at the docs for MediaStream. I have something now that isn't erroring out. All I need is the correct Mime for the blob so I can use it in the iFrame src.
Here is what I have now that returns the srcObject:
var binaryData = [];
binaryData.push(data); //My blob
var foo = URL.createObjectURL(new Blob(binaryData, {type: "application/text"}));
console.log(foo); //gives me the correct object
Should I be using a Mime of "text"? I need to assign that object to the iFrame src.
EDIT3:
Using a MIME of text/plain
, I get the following in the DOM:
<iframe id="iframe-target" src="blob:http://192.168.112.12/e25a4404-8233-44f0-86b3-1fff1109805f" width="100%" height="100%">
#Document
<html>
<head></head>
<body>
<pre style="word-wrap: break-word; white-space: pre-wrap;">[object Object]</pre> <--'object Object' is the issue
</body>
</html>
</iframe>
I now see the blob object in the iframe but the HTML within the iframe is showing as an Object. The object is actually a PDF but as it is, I can't view it. I still think this is a MIME issue, but I'm not sure what to use.
The URL. createObjectURL() static method creates a string containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.
revokeObjectURL() The URL. revokeObjectURL() static method releases an existing object URL which was previously created by calling URL. createObjectURL() . Call this method when you've finished using an object URL to let the browser know not to keep the reference to the file any longer.
createObjectURL is a static method provided by the URL Web API. Returns a DOMString containing a unique blob URL, that is a URL with blob: as its scheme, followed by an opaque string uniquely identifying the object in the browser.
createObjectURL is synchronous but it seems to complete almost instantaneously. Also note that calling URL. revokeObjectURL in the image's onload handler breaks "Open image in New Tab" in the image's context menu.
I think you can still use Content-type: application/pdf
on the response, the point is to receive a valid blob.
When creating the object URL, assuming data
is still your blob, you should do:
var blobObj = new Blob([atob(data)], { type: "application/pdf" });
var url = window.URL.createObjectURL(blobObj);
document.getElementById("iframe-target").setAttribute("src", url);
Here, a few things are happening:
data
is converted back to binary with atob()
Blob()
constructorI've created a snippet as a small demo, here you can choose a local PDF file, which will be converted to base64, then used as the src
attribute in an iframe. See the source code on CodeSandbox and see the demo of the sandbox here.
UPDATE: Removed embedded snippet.
As @K J pointed out in the comments, running the snippet embedded or from the CodeSandbox editor will produce errors.
At first glance, it appears that the browser blocks the resulting blob URL. This is because window.URL.createObjectURL
prepends the blob URL differently based on the origin.
This isn't a problem in production, but makes demoing the solution a bit more difficult. Luckily, CodeSandbox deploys the app to a host, where the blob URL scheme and host will match the app URL:
In this case, the PDF will be shown as expected. I've tested the deployed version of the sandbox on Chrome, Safari, and Firefox.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With