-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add URL.createObjectURL and URL.revokeObjectURL #1721
Comments
Can the implementation in https://github.com/eligrey/Blob.js be used in I'm blocked by this for using |
No, the code there appears to create data URLs, not blob URLs. Someone needs to properly implement the spec at https://w3c.github.io/FileAPI/#dfn-createObjectURL |
I'm not familiar with this, will it be something like this? createObjectURL(blob) {
var implementationDefinedValue = ???
var url = `blob:${asciiSerialize(location.origin) || implementationDefinedValue}/${createUUID()}`;
saveToBlobStore(url, blob);
return url;
}
revokeObjectURL(blobUrl) {
// assume `getFromBlobStore()` will not throw
var blob = getFromBlobStore(blobUrl);
if (!blob) {
throw new NetworkError(...);
}
removeFromBlobStore(blobUrl);
} |
@unional I think Chrome isn't following the spec strictly, Edit: |
That means: const uuid = require('uuid/v4');
createObjectURL(blob) {
var implementationDefinedValue = ???
var url = `blob:${asciiSerialize(location.origin) || implementationDefinedValue}/${uuid()}`;
return url;
}
revokeObjectURL(blobUrl) {
return;
}
asciiSerialize(origin) {
if (origin.scheme) {
return `${origin.scheme}://${serializeHost(origin.host)}${origin.port? ':' + +origin.port : ''}`;
}
else {
return 'null';
}
}
serializeHost(host) {
...
} I guess there is a One last thing is:
What does "implementation-defined value" mean? |
Seems like I get all the questions answered. I think it is ready to be implemented at https://github.com/jsdom/whatwg-url UPDATE: Turns out const uuid = require('uuid/v4');
createObjectURL(_blob) {
var url = `blob:${serializeURL(location.origin)}/${uuid()}`;
return url;
}
revokeObjectURL(_blobUrl) {
return;
} However I don't know how the @domenic , it the code above looks good and can be added there? Can you add it? |
It ought to do more than just make the Blob URLs. It ought to subsequently allow a URL so generated to be provided to the likes of |
Does it need that? What is the use cases? Would the existing logic of I'm not sure if the goal of IMO we should defer this until there is an actual use case. What else can we do to move this forward? |
The |
There's definitely no interest in adding object URLs to jsdom if they don't actually work (when used by XHR, img elements, etc.). Just creating them is very, very uninteresting. You can do that with a few lines of code; you don't need a whole jsdom implementation for that. |
Ok, so what's need to implement that? |
Besides allowing DOM APIs to be used in Node, It is very helpful to have such a browser for running automated tests. But a specific use case for Node usage is that if you are running browser/Node code where a Blob gets created, this method can be used in both environments to allow you to introspect on the contents (as the browser at least otherwise does not allow this). (In my case, it would allow me to avoid writing Node-specific code for cloning Blobs in the structured cloning algorithm as used by IndexedDB (and Blob URLs meet a special need of working in memory independent of a server. I think there are three unique aspects of Blob URLs over One is that beyond in-memory content , they can reference files without needing to encode the whole file's contents within the URL (and not requiring it to be dereferenced until used). Two is that they might be useful for security/privacy in avoiding persistence of the data beyond a browser session or outside of the user's browser. Third is that Blob URLs can be revoked even within a session, allowing references to expire (e.g., if you create an image, display it via a Blob URL, and then the user deletes the image, you can revoke the URL so that the Blob URL cannot be reused, unlike would be the case with say a |
I want to do server side rendering of React (CRA) project with the help of react-snapshot. My project also uses react-mapbox-gl, which in turn uses mapbox-gl, which uses webworkify. And process fails because of
I'm not interested in actually rendering map on server, I just want to render placeholder instead of map on server, but this error prevents it.
Is there a way I can patch jsdom to at least to add noop function for this? I suppose it will fail, but this at least will be starting point. |
Thanks. It's a pity I'm stuck with old api e.g. options.beforeParse(this[window]._globalProxy); (facepalm) it will be a bit harder UPD there is created: (err, window) => {
window.URL = { createObjectURL: () => {} }
} |
What's the status of this feature request? It would certainly be useful to have. |
@fredvollmer if using jest with jsdom and you want to noop this function you can add this code to function noOp () { }
if (typeof window.URL.createObjectURL === 'undefined') {
Object.defineProperty(window.URL, 'createObjectURL', { value: noOp})
} |
@dylanjha I get |
@franciscolourenco you're right! Sorry about that... just updated the code in the above example to wrap in this conditional and that is working for me: Give that a try! Thanks for reminding me to come back here and update my example. |
@dylanjha
|
Does anybody know if this can be applied with gulp too? Basically I want to silence the jsdom errors about Thanks in advance! |
This is hacky and I would not recommend it, but I made a simplified implementation of |
Apparently, URL.createObjectUrl is not supported in JSDom, see: jsdom/jsdom#1721 With FileReader we have the option to avoid it altogether.
(hope it can be usefull for someone ...) I use Jest with FakeIndexedDB for my app's unit tests, and I was stucked because I needed URL.createObjectURL to work in jsdom. I could not use noOp, otherwise my tests would be meaningless. I was finally able to implement a working mock for URL.createObjectURL, by using stuff from eligrey/Blob.js. |
jsdom-worker adds a working implementation of |
@lucaswiman do you have example code how to use it? I am trying to mock import 'jsdom-worker';
import { Blob } from 'blob-polyfill';
global.Blob = Blob;
// TypeError: URL.createObjectURL is not a function
Object.defineProperty(window.URL, 'createObjectURL', {
value: jest.fn().mockImplementation((file) => {
let result = null;
const code = `onmessage = e => postMessage(e.data)`;
const worker = new Worker(URL.createObjectURL(new Blob([code])));
worker.onmessage = (arg) => {
result = arg;
};
worker.postMessage(file);
return result;
}),
}); |
@nemanjam If you're using "jest": {
"setupFiles": [
"jsdom-worker"
]
} |
It works, thanks, I lost 3 days to mock |
Good thread with a couple of workarounds, but it is still unclear: |
The plan is for you to send a pull request! |
still open from 2017, say hi from 2022.
still here. and |
How to force Jest/jsdom to use Node.js // FixJSDOMEnvironment.ts
import JSDOMEnvironment from 'jest-environment-jsdom';
// https://github.com/facebook/jest/blob/v29.4.3/website/versioned_docs/version-29.4/Configuration.md#testenvironment-string
export default class FixJSDOMEnvironment extends JSDOMEnvironment {
constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
super(...args);
// FIXME https://github.com/jsdom/jsdom/issues/1721
this.global.URL = URL;
this.global.Blob = Blob;
}
} // jest.config.js
/** @type {import('jest').Config} */
const config = {
testEnvironment: './FixJSDOMEnvironment.ts',
...
}
module.exports = config; See also #1724 (comment), #3363 (comment) |
@tkrotoff thanks for your suggestion -
UPDATE: nvm, my
|
Hi,
jsdom
already supports theURL
constructor, but not these 2 static methods, they are supported in most modern browsers.createObjectURL
revokeObjectURL
Can I use
The text was updated successfully, but these errors were encountered: