var canvasPromise = html2canvas(document.body, {
allowTaint: true,
useCORS: true
});
canvasPromise.then(function(canvas) {
document.body.appendChild(canvas);
console.log(canvas);
canvas.toDataURL('image/png');
});
غير معلوم (في الوعد) DOMException: فشل تنفيذ "toDataURL" على "HTMLCanvasElement": قد لا يتم تصدير اللوحات الملوثة.
لدي أيضا نفس القضايا.
هل وجدت حلا أو حلا؟
أفعل نفس الشيء في Firefox 61.0.2 وأحصل على خطأ أمان على الرغم من تعيين allowTaint إلى true
لا يوجد حل على حد علمي ، ولكن لدي حل بديل: قم بتغيير كل صورة إلى base64. بهذه الطريقة ، يمكنك عرضها في لوحة الرسم على الرغم من أنها في الأصل من مجال مختلف.
هل رأيت هذا: CORS_enabled_image
إذا كان مصدر المحتوى الأجنبي هو HTML ، محاولة استرداد محتويات اللوحة غير مسموح بها.
بمجرد رسم أي بيانات تم تحميلها من مصدر آخر دون موافقة CORS في لوحة الرسم ، تصبح اللوحة ملوثة.
أستخدم خيارات التكوين مثل هذا:
html2canvas(document.body, {
allowTaint: true,
foreignObjectRendering: true
});
مرحبًا ، لقد واجهنا نفس المشكلة. لقد اتبعنا اقتراح
إذا وجد شخص ما أنه مفيد كان الحل:
html2canvas(document.body, {
proxy: this._proxyURL,
allowTaint: true,
onclone: (cloned) => convertAllImagesToBase64(this._proxyURL, cloned),
}).then((canvas) => {
this._postmessageChannel.send(`get.screenshot:${canvas.toDataURL('image/png')}`);
});
حيث تكون الوظيفة المساعدة convertAllImagesToBase64 هي:
const convertAllImagesToBase64 = (proxyURL, cloned) => {
const pendingImagesPromises = [];
const pendingPromisesData = [];
const images = cloned.getElementsByTagName('img');
for (let i = 0; i < images.length; i += 1) {
// First we create an empty promise for each image
const promise = new Promise((resolve, reject) => {
pendingPromisesData.push({
index: i, resolve, reject,
});
});
// We save the promise for later resolve them
pendingImagesPromises.push(promise);
}
for (let i = 0; i < images.length; i += 1) {
// We fetch the current image
fetch(`${proxyURL}?url=${images[i].src}`)
.then((response) => response.json())
.then((data) => {
const pending = pendingPromisesData.find((p) => p.index === i);
images[i].src = data;
pending.resolve(data);
})
.catch((e) => {
const pending = pendingPromisesData.find((p) => p.index === i);
pending.reject(e);
});
}
// This will resolve only when all the promises resolve
return Promise.all(pendingImagesPromises);
};
export { convertAllImagesToBase64 };
بالمناسبة ، هذه هي الاختبارات لهذه الوظيفة المساعدة (نحن نستخدم jest لاختبار wrting وحزم mockFetch):
import { convertAllImagesToBase64 } from '../images';
fetch.resetMocks();
// Mock fetch to respond different for each image so we can assert that the image return the correct response
// Also make one of the response be delayed (2 seconds) to simulate the response is not in the same order we do the call (network latency, image size, etc)
fetch.mockImplementation((url) => {
if (url.includes('imagesrc1')) {
return Promise.resolve(new Response(JSON.stringify('data:image/png;base64,1')));
} else if (url.includes('imagesrc2')) {
return new Promise((resolve) => setTimeout(resolve(new Response(JSON.stringify('data:image/png;base64,2'))), 2000));
} else if (url.includes('imagesrc3')) {
return Promise.resolve(new Response(JSON.stringify('data:image/png;base64,3')));
}
return Promise.resolve(new Response(JSON.stringify('')));
});
const mocksImages = [
{ id: 1, src: 'imagesrc1' },
{ id: 2, src: 'imagesrc2' },
{ id: 3, src: 'imagesrc3' },
];
const mockClone = {
getElementsByTagName: jest.fn(() => mocksImages),
};
describe('utils/images', () => {
it('convertAllImagesToBase64. Expect to call 3 times to the correct enpoint using the image source', async () => {
const allPromises = convertAllImagesToBase64('http://localhost/fake_proxy', mockClone);
// Expect the clone elements gets all the image tags
expect(mockClone.getElementsByTagName).toBeCalledWith('img');
allPromises.then(() => {
// Expect to have done the 3 fetch calls and with the correct params
expect(fetch).toBeCalledTimes(3);
expect(fetch).toHaveBeenNthCalledWith(1, 'http://localhost/fake_proxy?url=imagesrc1');
expect(fetch).toHaveBeenNthCalledWith(2, 'http://localhost/fake_proxy?url=imagesrc2');
expect(fetch).toHaveBeenNthCalledWith(3, 'http://localhost/fake_proxy?url=imagesrc3');
// Expect that our images where updated properly
expect(mocksImages).toContainEqual({
id: 1, src: 'data:image/png;base64,1',
});
expect(mocksImages).toContainEqual({
id: 2, src: 'data:image/png;base64,2',
});
expect(mocksImages).toContainEqual({
id: 3, src: 'data:image/png;base64,3',
});
});
});
});
روبي الخلفية enpdoint:
require 'base64'
require 'net/http'
module Api
module V1
class ImageProxyController < ApiController
def index
url = URI.parse(params[:url])
image = Net::HTTP.get_response(url)
render json: data_url(image).to_json, callback: params[:callback]
end
private
def data_url(image)
"data:#{image.content_type};base64,#{Base64.encode64(image.body)}"
end
end
end
end
آمل أن يجد شخص ما هذا مفيدًا. آمل أن يساعد ذلك شخصًا ما على عدم استثمار الكثير من الوقت كما فعلنا لإصلاح ذلك بشكل صحيح.
إذا كنت تستطيع أن ترى أي تحسن يرجى اقتراح.
يعتبر.
إذا كنت تحب أدناه ، فماذا سيحدث؟
const TempImage = window.Image
const Image = function() {
const img = new TempImage()
img.crossOrigin = 'anonymous'
return img
}
وجدت حلا وهو يعمل
أثناء استدعاء html2canvas ، مرر useCORS إلى true
html2canvas (selectorElement ، {useCORS: true} ). ثم (canvas => {
//قم بعمل ما
}) ؛
ملف html2canvas.js الصحيح. هناك خطأ مطبعي
غيّر "مجهول" إلى "مجهول" في كتلة if هذه
إذا (isInlineBase64Image (src) || useCORS) {
img.crossOrigin = 'مجهول' ؛
}
var canvasPromise = html2canvas(document.body, { allowTaint: true, useCORS: true }); canvasPromise.then(function(canvas) { document.body.appendChild(canvas); console.log(canvas); canvas.toDataURL('image/png'); });
تقارير الأخطاء:
غير معلوم (في الوعد) DOMException: فشل تنفيذ "toDataURL" على "HTMLCanvasElement": قد لا يتم تصدير اللوحات الملوثة.
- تم اختبار إصدار html2canvas باستخدام:
- Chrome 67.0.3396.99
- نظام التشغيل Windows 10
ستحتاج إلى استخدام الخاصية "useCORS: true" فقط ، إذا كنت تستخدم الخاصية "allowTaint: true" ، فأنت تعطي تمويجًا لتحويل قماشك إلى لوحة قماشية ملوثة
استخدم هذا:
var canvasPromise = html2canvas(document.body, {
useCORS: true
});
canvasPromise.then(function(canvas) {
document.body.appendChild(canvas);
console.log(canvas);
canvas.toDataURL('image/png');
});
بدلا من هذا:
var canvasPromise = html2canvas(document.body, {
allowTaint: true,
useCORS: true
});
canvasPromise.then(function(canvas) {
document.body.appendChild(canvas);
console.log(canvas);
canvas.toDataURL('image/png');
});
مرحبًا ، عمل رائع لـ html2canvas.
للأسف أنا أواجه نفس المشكلة ، هل قام أحد بحل هذه المشكلة؟
جربت بالفعل motarock وكل ما قبل ذلك ، بالإضافة إلى التوليفات ، إلخ. الصورة بيضاء بدون أي شيء.
downloadQRCode = (fileName) => {
html2canvas(document.getElementById('generated-qr-code'), {
useCORS: true,
// allowTaint: false,
// logging: true,
}).then((canvas) => {
// document.body.appendChild(canvas); // checking
const data = canvas.toDataURL('image/jpeg');
const element = document.createElement('a');
element.setAttribute('href', data);
element.setAttribute('download', fileName + '.jpeg');
document.body.appendChild(element);
element.click();
// document.body.removeChild(element);
console.log("%c data", "font-size:2em;", data, fileName);
console.log("%c canvas", "font-size:2em;", canvas );
this.setState({
imageSrc: data // setting the src of a img tag to check the result. Nothing in it either..
})
});
شكرا لك مقدما
لدي أيضا نفس القضايا.
يمكن لأي شخص إصلاح هذه المشكلة؟
:( نفس المشكلة. لدينا html مع svg المتداخلة ولن يتم عرضها
جربت بالفعل motarock وكل ما قبل ذلك ، بالإضافة إلى التوليفات ، إلخ. الصورة بيضاء بدون أي شيء.
لدي هذه المشكلة عندما لا أستخدم SSL ، حيث يعمل SSL بشكل مثالي
التعليق الأكثر فائدة
لدي أيضا نفس القضايا.
هل وجدت حلا أو حلا؟