https://github.com/eligrey/Blob.js 中的实现可以在jsdom
吗?
我因在jsdom
使用jspdf
被阻止。
不,那里的代码似乎是创建数据 URL,而不是 Blob URL。 有人需要在https://w3c.github.io/FileAPI/#dfn -createObjectURL 正确实施规范
我不熟悉这个,会不会是这样的?
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 createUUID
可以是uuidV4
我认为 Chrome 没有严格遵循规范,如果您两次传递相同的 args 或任何不期望的类型,如数字或数组, URL.revokeObjectURL
不会抛出NetworkError
。
编辑:
Firefox 也是如此,为了保持实现简单并且像浏览器一样,我认为不需要 blob 存储并且URL.revokeObjectURL
可以是一个 noop 函数。
这意味着:
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) {
...
}
我想代码中已经有serializeHost()
了。
最后一件事是:
如果序列化为“null”,则将其设置为实现定义的值。
“实现定义的价值”是什么意思?
我认为它已准备好在https://github.com/jsdom/whatwg-url实施
更新:原来whatwg-url
有大部分可用的东西。 所以我想代码很简单:
const uuid = require('uuid/v4');
createObjectURL(_blob) {
var url = `blob:${serializeURL(location.origin)}/${uuid()}`;
return url;
}
revokeObjectURL(_blobUrl) {
return;
}
但是我不知道whatwg-url
是如何组织的。 所以不知道怎么把代码放进去。
@domenic ,上面的代码看起来不错,可以添加到那里吗? 你能加吗?
它应该做的不仅仅是制作 Blob URL。 它应该随后允许将如此生成的 URL 提供给XMLHttpRequest
。
它应该做的不仅仅是制作 Blob URL。 它应该随后允许将如此生成的 URL 提供给 XMLHttpRequest 之类的东西。
它需要那个吗? 用例是什么? XMLHttpRequest
的现有逻辑会很好地处理它吗?
我不确定jsdom
的目标是否是复制浏览器所做的确切行为。
如果是这种情况,我们正在编写浏览器。
IMO 我们应该推迟到有实际用例。
我们还能做些什么来推动这一进程?
var url =
blob:${serializeURL(location.origin)}/${uuid()}
;
serializeURL()
比规范中描述的算法做的更多。
我们应该完全按照规范使用它还是实现它?
如果它们实际上不起作用(当被 XHR、img 元素等使用时),绝对没有兴趣将对象 URL 添加到 jsdom。 仅仅创造它们是非常非常无趣的。 你可以用几行代码做到这一点; 你不需要一个完整的 jsdom 实现。
好的,那么需要什么来实现呢?
除了允许在 Node 中使用 DOM API 之外,拥有这样一个浏览器来运行自动化测试是非常有帮助的。
但是 Node 使用的一个特定用例是,如果您在创建 Blob 的地方运行浏览器/Node 代码,则可以在两种环境中使用此方法以允许您内省内容(因为浏览器至少不允许这个)。 (在我的例子中,它允许我避免在 IndexedDB(和postMessage
)使用的结构化克隆算法中编写节点特定的代码来克隆 Blob。)
Blob URL 满足在独立于服务器的内存中工作的特殊需求。 我认为 Blob URL 在data:
URL 上有三个独特的方面(除了能够更轻松地组合它们而无需转义等)。
一是除了 in-memory content 之外,他们可以引用文件而无需在 URL 中对整个文件的内容进行编码(并且在使用之前不需要取消引用)。
二是它们可能对安全/隐私有用,可以避免数据在浏览器会话之外或用户浏览器之外的持久化。
第三是即使在会话中也可以撤销 Blob URL,从而允许引用过期(例如,如果您创建一个图像,通过 Blob URL 显示它,然后用户删除该图像,您可以撤销该 URL,以便 Blob URL 不能重复使用,不像data
URL 的情况)。
如果它们实际上不起作用(当被 XHR、img 元素等使用时),绝对没有兴趣将对象 URL 添加到 jsdom。 仅仅创造它们是非常非常无趣的。
我想在react-snapshot的帮助下react-mapbox-gl ,它反过来使用 mapbox-gl ,它使用webworkify 。 并且过程失败,因为
Error: Uncaught [TypeError: o.URL.createObjectURL is not a function]
我对在服务器上实际渲染地图不感兴趣,我只想在服务器上渲染占位符而不是地图,但是这个错误阻止了它。
你可以用几行代码做到这一点; 你不需要一个完整的 jsdom 实现。
有没有办法可以修补 jsdom 至少为此添加 noop 功能? 我想它会失败,但这至少是起点。
请参阅自述文件: https :
谢谢。 很遗憾我一直坚持使用旧的 api 例如jsdom.env
,它没有这个
options.beforeParse(this[window]._globalProxy);
(facepalm) 会有点难
UPD
有created
回调
created: (err, window) => {
window.URL = { createObjectURL: () => {} }
}
此功能请求的状态如何? 拥有它肯定会很有用。
@fredvollmer如果在 jsdom 中使用 jest 并且你想 noop 这个函数,你可以将此代码添加到setupTest.js
(或等效的设置脚本)
function noOp () { }
if (typeof window.URL.createObjectURL === 'undefined') {
Object.defineProperty(window.URL, 'createObjectURL', { value: noOp})
}
@dylanjha我得到TypeError: Cannot redefine property: createObjectURL
@franciscolourenco你说得对! 抱歉……刚刚更新了上面示例中的代码以包含在这个条件中,这对我有用: if (typeof window.URL.createObjectURL === 'undefined') {
试试看!
感谢您提醒我回到这里并更新我的示例。
@dylanjha createObjectURL
已定义但不是函数,因此某些库会引发错误。 一项任务对我有用:
window.URL.createObjectURL = noOp
有人知道这是否也适用于 gulp 吗? 基本上,我想消除来自 uncss 正在使用的 jsdom 的关于createObjectURL
的 jsdom 错误。
提前致谢!
if (typeof URL !== 'undefined') {
delete URL;
}
只是为了使它更加清楚,做类似的事情
function noOp () { }
if (typeof window.URL.createObjectURL === 'undefined') {
Object.defineProperty(window.URL, 'createObjectURL', { value: noOp})
}
仅当您将其放在 jest 配置的“setupFiles”文件中时才有效。 所以在你的 package.json 或任何你拥有的地方"jest": {
"setupFiles": [
"<rootDir>/internals/testing/setup_file.js"
],
}
您将其他人编写的代码放入该文件中。 (如果该文件不存在,您可能需要创建它)
希望这可以帮助任何对解决方案感到困惑的人
img.src = URL.createObjectURL(blob);
不工作,在检查 jest 测试用例文件时收到错误URL.createObjectURL 不是函数。
有没有其他方法可以将返回的 blob 分配给图像 src ? 我被屏蔽了
最有用的评论
@fredvollmer如果在 jsdom 中使用 jest 并且你想 noop 这个函数,你可以将此代码添加到
setupTest.js
(或等效的设置脚本)