Jsdom: Tambahkan URL.createObjectURL dan URL.revokeObjectURL

Dibuat pada 31 Jan 2017  ·  26Komentar  ·  Sumber: jsdom/jsdom

Hai, jsdom sudah mendukung konstruktor URL , tetapi bukan 2 metode statis ini, mereka didukung di sebagian besar browser modern.

buatObjectURL
mencabutObjectURL
Bisakah saya menggunakan?

feature

Komentar yang paling membantu

@fredvollmer jika menggunakan lelucon dengan jsdom dan Anda ingin menghentikan fungsi ini, Anda dapat menambahkan kode ini ke setupTest.js (atau skrip pengaturan yang setara)

function noOp () { }

if (typeof window.URL.createObjectURL === 'undefined') {
  Object.defineProperty(window.URL, 'createObjectURL', { value: noOp})
}

Semua 26 komentar

Bisakah implementasi di https://github.com/eligrey/Blob.js digunakan di jsdom ?

Saya diblokir oleh ini karena menggunakan jspdf di dalam jsdom .

Tidak, kode di sana tampaknya membuat URL data, bukan URL gumpalan. Seseorang perlu menerapkan spesifikasi dengan benar di https://w3c.github.io/FileAPI/#dfn -createObjectURL

Saya tidak terbiasa dengan ini, apakah akan seperti ini?

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 bisa uuidV4

Saya pikir Chrome tidak mengikuti spesifikasi secara ketat, URL.revokeObjectURL tidak akan membuang NetworkError jika Anda melewatkan argumen yang sama dua kali atau jenis apa pun yang tidak diharapkan, seperti angka atau larik.

Sunting:
Hal yang sama terjadi dengan Firefox, untuk menjaga implementasi tetap sederhana dan seperti browser, saya pikir tidak perlu memiliki blob store dan URL.revokeObjectURL dapat menjadi fungsi noop.

Itu berarti:

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) {
  ...
}

Saya kira sudah ada serializeHost() di suatu tempat dalam kode.

Satu hal terakhir adalah:

Jika serial adalah "null", setel ke nilai yang ditentukan implementasi.

Apa yang dimaksud dengan "nilai yang ditentukan implementasi"?

Sepertinya saya mendapatkan semua pertanyaan yang dijawab.
http://stackoverflow.com/questions/42452543/what-does-implementation-defined-value-in-fileapi-unicodebloburl-mean/42452714#42452714

Saya pikir itu siap untuk diimplementasikan di https://github.com/jsdom/whatwg-url

UPDATE: Ternyata whatwg-url memiliki banyak hal yang tersedia. Jadi saya kira kodenya sederhana:

const uuid = require('uuid/v4');

createObjectURL(_blob) {
  var url = `blob:${serializeURL(location.origin)}/${uuid()}`;
  return url;
}
revokeObjectURL(_blobUrl) {
  return;
}

Namun saya tidak tahu bagaimana whatwg-url diatur. Jadi tidak tahu cara memasukkan kodenya.

@domenic , apakah kode di atas terlihat bagus dan dapat ditambahkan di sana? Bisakah Anda menambahkannya?

Seharusnya melakukan lebih dari sekadar membuat URL Blob. Seharusnya selanjutnya memungkinkan URL yang dihasilkan untuk diberikan kepada orang-orang seperti XMLHttpRequest .

Seharusnya melakukan lebih dari sekadar membuat URL Blob. Seharusnya selanjutnya memungkinkan URL yang dihasilkan untuk diberikan kepada orang-orang seperti XMLHttpRequest.

Apakah itu membutuhkan itu? Apa kasus penggunaan? Apakah logika XMLHttpRequest menanganinya dengan baik?

Saya tidak yakin apakah tujuan dari jsdom adalah untuk mereplikasi perilaku persis seperti yang dilakukan browser.
Jika demikian, kami sedang menulis browser.

IMO kita harus menunda ini sampai ada kasus penggunaan yang sebenarnya.

Apa lagi yang bisa kita lakukan untuk memajukan ini?

var url = blob:${serializeURL(location.origin)}/${uuid()} ;

serializeURL() melakukan sedikit lebih banyak daripada algoritme yang dijelaskan dalam spesifikasi.
Haruskah kita menggunakannya atau mengimplementasikannya persis seperti dalam spesifikasi?

Jelas tidak ada minat untuk menambahkan URL objek ke jsdom jika tidak benar-benar berfungsi (saat digunakan oleh XHR, elemen img, dll.). Hanya membuat mereka sangat, sangat tidak menarik. Anda dapat melakukannya dengan beberapa baris kode; anda tidak memerlukan seluruh implementasi jsdom untuk itu.

Ok, jadi apa yang dibutuhkan untuk mengimplementasikannya?

Selain memungkinkan DOM API untuk digunakan di Node, sangat membantu untuk memiliki browser seperti itu untuk menjalankan pengujian otomatis.

Tetapi kasus penggunaan khusus untuk penggunaan Node adalah jika Anda menjalankan browser/kode Node tempat Blob dibuat, metode ini dapat digunakan di kedua lingkungan untuk memungkinkan Anda mengintrospeksi konten (setidaknya browser tidak mengizinkan ini). (Dalam kasus saya, itu akan memungkinkan saya untuk menghindari penulisan kode khusus Node untuk mengkloning Blob dalam algoritma kloning terstruktur seperti yang digunakan oleh IndexedDB (dan postMessage ).)

URL Blob memenuhi kebutuhan khusus untuk bekerja di memori yang tidak bergantung pada server. Saya pikir ada tiga aspek unik dari URL Blob lebih dari data: URL (selain dapat membuat mereka lebih mudah tanpa melarikan diri dan semacamnya).

Salah satunya adalah bahwa di luar konten dalam memori , mereka dapat mereferensikan file tanpa perlu menyandikan seluruh konten file di dalam URL (dan tidak mengharuskannya untuk direferensikan hingga digunakan).

Dua adalah bahwa mereka mungkin berguna untuk keamanan/privasi dalam menghindari persistensi data di luar sesi browser atau di luar browser pengguna.

Ketiga adalah bahwa URL Blob dapat dicabut bahkan dalam satu sesi, memungkinkan referensi kedaluwarsa (misalnya, jika Anda membuat gambar, menampilkannya melalui URL Blob, dan kemudian pengguna menghapus gambar, Anda dapat mencabut URL sehingga Blob URL tidak dapat digunakan kembali, tidak seperti halnya dengan misalnya URL data ).

Jelas tidak ada minat untuk menambahkan URL objek ke jsdom jika tidak benar-benar berfungsi (saat digunakan oleh XHR, elemen img, dll.). Hanya membuat mereka sangat, sangat tidak menarik.

Saya ingin melakukan rendering sisi server dari proyek React (CRA) dengan bantuan react-snapshot . Proyek saya juga menggunakan react-mapbox-gl , yang pada gilirannya menggunakan mapbox-gl, yang menggunakan webworkify . Dan proses gagal karena

Error: Uncaught [TypeError: o.URL.createObjectURL is not a function]

Saya tidak tertarik untuk benar-benar merender peta di server, saya hanya ingin merender placeholder alih-alih peta di server, tetapi kesalahan ini mencegahnya.

Anda dapat melakukannya dengan beberapa baris kode; anda tidak memerlukan seluruh implementasi jsdom untuk itu.

Apakah ada cara saya dapat menambal jsdom setidaknya untuk menambahkan fungsi noop untuk ini? Saya kira itu akan gagal, tetapi setidaknya ini akan menjadi titik awal.

Lihat readme: https://github.com/tmpvar/jsdom#intervening -before-parsing

Terima kasih. Sayang sekali saya terjebak dengan api lama misalnya jsdom.env , yang tidak memiliki ini

options.beforeParse(this[window]._globalProxy);

(telapak tangan) itu akan sedikit lebih sulit

UPD

ada panggilan balik created

created: (err, window) => {
  window.URL = { createObjectURL: () => {} }
}

Apa status permintaan fitur ini? Pasti bermanfaat untuk dimiliki.

@fredvollmer jika menggunakan lelucon dengan jsdom dan Anda ingin menghentikan fungsi ini, Anda dapat menambahkan kode ini ke setupTest.js (atau skrip pengaturan yang setara)

function noOp () { }

if (typeof window.URL.createObjectURL === 'undefined') {
  Object.defineProperty(window.URL, 'createObjectURL', { value: noOp})
}

@dylanjha saya mendapatkan TypeError: Cannot redefine property: createObjectURL

[email protected]

@franciscolourenco Anda benar! Maaf tentang itu... baru saja memperbarui kode dalam contoh di atas untuk membungkus kondisi ini dan itu berfungsi untuk saya: if (typeof window.URL.createObjectURL === 'undefined') {

Cobalah!

Terima kasih telah mengingatkan saya untuk kembali ke sini dan memperbarui contoh saya.

@dylanjha createObjectURL didefinisikan tetapi bukan fungsi, jadi beberapa perpustakaan melempar kesalahan. Sebuah tugas berhasil untuk saya:

window.URL.createObjectURL = noOp

Adakah yang tahu apakah ini bisa diterapkan dengan tegukan juga? Pada dasarnya saya ingin membungkam kesalahan jsdom tentang createObjectURL yang berasal dari jsdom yang digunakan uncss.

Terima kasih sebelumnya!

if (typeof URL !== 'undefined') {
  delete URL;
}

Hanya untuk membuatnya lebih jelas, melakukan sesuatu seperti

function noOp () { }

if (typeof window.URL.createObjectURL === 'undefined') {
  Object.defineProperty(window.URL, 'createObjectURL', { value: noOp})
}

hanya akan berfungsi jika Anda meletakkannya di dalam file "setupFiles" dari konfigurasi lelucon Anda. Jadi di package.json Anda atau di mana pun Anda miliki
"jest": { "setupFiles": [ "<rootDir>/internals/testing/setup_file.js" ], }
Anda meletakkan kode yang ditulis oleh orang lain di dalam file itu. (jika file itu tidak ada, Anda mungkin perlu membuatnya)

Semoga ini bisa membantu siapa pun yang bingung tentang solusinya

img.src = URL.createObjectURL(gumpalan);

tidak berfungsi, mendapatkan URL kesalahan.createObjectURL
apakah ada alternatif untuk menetapkan gumpalan yang dikembalikan ke gambar src? saya diblokir

Ini hacky dan saya tidak akan merekomendasikannya, tetapi saya membuat implementasi sederhana
Pastikan Anda tahu apa yang Anda lakukan sebelum menggunakannya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

potapovDim picture potapovDim  ·  4Komentar

khalyomede picture khalyomede  ·  3Komentar

amfio picture amfio  ·  3Komentar

cg433n picture cg433n  ·  3Komentar

kilianc picture kilianc  ·  4Komentar