Umumnya, tim akan memiliki nama domain khusus untuk menempatkan sumber daya statis, misalnya Tencent adalah gtimg.com, Baidu adalah bdimg.com; atau banyak tim menggunakan layanan Tencent Cloud atau Alibaba Cloud.
Nama domain halaman utama sering kali berbeda. Jika perlu melakukan operasi getImageData() atau toDataURL() pada gambar kanvas, masalah lintas domain akan muncul, dan terdapat lebih dari satu tingkat masalah lintas domain.
Pertama, pada langkah pertama, server gambar perlu mengkonfigurasi informasi Access-Control-Allow-Origin, misalnya:
Misalnya, PHP menambahkan informasi header respons, dan wildcard * menunjukkan bahwa nama domain apa pun diperbolehkan:
header(Access-Control-Allow-Origin: *);
Atau tentukan nama domain:
header(Access-Control-Allow-Origin: www.zhangxinxu.com);
Pada titik ini, browser Chrome tidak lagi memiliki pesan kesalahan terkait Access-Control-Allow-Origin, namun akan ada pesan kesalahan lintas domain lainnya.
2. Masalah lintas domain gambar kanvas getImageData lintas asalUntuk gambar lintas domain, selama dapat ditampilkan secara normal di halaman web, gambar tersebut dapat digambar menggunakan API drawImage() kanvas. Namun jika Anda ingin melangkah lebih jauh dan mendapatkan informasi piksel lengkap dari gambar melalui metode getImageData(), Anda mungkin akan membuat kesalahan.
Misalnya, gunakan kode berikut untuk mendapatkan informasi gambar avatar Anda sendiri di github:
var kanvas = dokumen.createElement('kanvas');var konteks = kanvas.getContext('2d');var img = Gambar baru();img.onload = fungsi () { konteks.drawImage(ini, 0, 0) ; konteks.getImageData(0, 0, ini.lebar, ini.tinggi);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Hasilnya adalah kesalahan berikut yang ditampilkan di bawah browser Chrome:
DOMException yang tidak tertangkap: Gagal mengeksekusi 'getImageData' pada 'CanvasRenderingContext2D': Kanvas telah tercemar oleh data lintas asal.
Kesalahan browser Firefox adalah:
SecurityError: Operasi ini tidak aman.
Jika metode canvas.toDataURL() digunakan, metode ini akan melaporkan:
Gagal mengeksekusi 'toDataURL' pada 'HTMLCanvasElement': Kanvas yang tercemar tidak dapat diekspor
Alasannya sebenarnya sama, disebabkan oleh lintas domain.
Jadi apakah ada cara untuk mengatasi masalah ini?
Anda dapat mencoba atribut crossOrigin.
3. Atribut HTML crossOrigin memecahkan masalah sumber daya lintas domainDalam HTML5, beberapa elemen menyediakan atribut yang mendukung CORS (Cross-Origin Resource Sharing) (berbagi sumber daya lintas asal). Elemen tersebut antara lain <img>, <video>, <script>, dll., dan nama atribut yang diberikan adalah atribut crossOrigin.
Oleh karena itu, masalah lintas domain di atas dapat ditangani seperti ini:
var kanvas = dokumen.createElement('kanvas');var konteks = kanvas.getContext('2d');var img = Gambar baru();img.crossOrigin = '';img.onload = fungsi () { konteks.drawImage (ini, 0, 0); konteks.getImageData(0, 0, ini.lebar, ini.tinggi);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
Cukup tambahkan img.crossOrigin = ''. Meskipun kode JS di sini menetapkan string kosong, nilai atribut sebenarnya yang berfungsi adalah anonim.
crossOrigin dapat memiliki dua nilai berikut:
Kata kunci | Definisi |
---|---|
anonim | Permintaan sumber daya lintas asal untuk elemen tidak memerlukan tanda kredensial untuk disetel. |
kredensial penggunaan | Permintaan sumber daya lintas-domain untuk elemen memerlukan tanda kredensial untuk disetel, artinya kredensial diperlukan untuk permintaan tersebut. |
Diantaranya, selama nilai atribut crossOrigin bukan kredensial penggunaan, semuanya akan diurai sebagai anonim, termasuk string kosong, termasuk karakter seperti 'abc'.
Misalnya:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // Hasilnya adalah 'anonim'
Hal lain yang perlu diperhatikan adalah meskipun tidak ada atribut crossOrigin, dan pengaturan crossOrigin=use-credentials akan melaporkan kesalahan lintas domain secara default, keduanya berbeda sifatnya.
kompatibilitas crossOriginBrowser IE11+ (IE Edge), Safari, Chrome, dan Firefox semuanya mendukungnya IE9 dan IE10 akan melaporkan SecurityError, seperti yang ditunjukkan pada gambar di bawah:
4. Mengapa atribut crossOrigin dapat menyelesaikan masalah sumber daya lintas domain?crossOrigin=anonymous Daripada memberi tahu server lain, Anda tidak perlu membawa informasi non-anonim apa pun. Misalnya cookies, oleh karena itu browser yang ada saat ini pasti aman.
Ini seperti Anda ingin pergi ke rumah seseorang untuk mengambil sepotong pakaian. crossOrigin=anonymous berbeda dengan memberi tahu orang lain bahwa saya hanya menginginkan pakaian itu dan tidak yang lain. Jika Anda tidak memberi tahu mereka, pihak lain mungkin memasukkan alat penyadap atau sesuatu ke dalam pakaiannya, yang tidak aman dan browser akan memblokirnya.
5. Apa yang harus saya lakukan jika browser IE10 tidak mendukung crossOrigin?Saat kami meminta gambar, kami tidak langsung menggunakan Image() baru, tetapi menggunakan ajax dan metode URL.createObjectURL() untuk menyelamatkan negara.
Kodenya adalah sebagai berikut:
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image(); Anda dapat menggunakan kanvas untuk melakukan apa pun yang Anda inginkan dengan img // ... kode ... // Ingatlah untuk melepaskan memori setelah menggunakan gambar URL.revokeObjectURL(url }; = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
Metode ini tidak hanya OK untuk browser IE10, tetapi juga didukung oleh semua browser yang awalnya mendukung crossOrigin.
Itu hanya memerlukan satu permintaan ajax lagi, itu tidak masalah!
Menurut praktiknya, di bawah browser IE, jika gambar yang diminta terlalu besar, beberapa ribu piksel, gambar akan gagal dimuat.
6. KesimpulanSedikit pengalaman kerja yang saya pelajari akhir-akhir ini, semoga dapat membantu teman-teman yang mengalami permasalahan serupa. Saya juga berharap semua orang mendukung VeVb Wulin Network.