क्रॉस-ओरिजिन टेंटेड कैनवास समस्या
जब एक कैनवास पर क्रॉस-ओरिजिन (अलग डोमेन/सबडोमेन/पोर्ट/प्रोटोकॉल) से छवि खींची जाती है, तो कैनवास "टेंटेड" (दूषित) हो जाता है। एक बार टेंटेड होने पर, getImageData(), toDataURL(), toBlob() जैसे मेथड्स सुरक्षा त्रुटि फेंकते हैं।
समाधान: crossOrigin एट्रिब्यूट + CORS हेडर
दोनों पक्षों पर कॉन्फ़िगरेशन आवश्यक है:
1. क्लाइंट-साइड: crossOrigin एट्रिब्यूट सेट करें
<!-- HTML में -->
<img id="externalImg" src="https://cdn.example.com/image.jpg" crossOrigin="anonymous">
<!-- या JavaScript में -->
<script>
const img = new Image();
img.crossOrigin = "anonymous"; // या "use-credentials"
img.src = "https://cdn.example.com/image.jpg";
img.onload = function() {
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// अब यह काम करेगा
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const dataURL = canvas.toDataURL('image/png');
};
</script>
2. सर्वर-साइड: CORS हेडर सेट करें
छवि होस्ट करने वाले सर्वर को उचित CORS हेडर भेजने होंगे:
# Apache (.htaccess या httpd.conf)
Header set Access-Control-Allow-Origin "*"
# या विशिष्ट डोमेन के लिए
Header set Access-Control-Allow-Origin "https://yoursite.com"
# Nginx
add_header Access-Control-Allow-Origin "*";
# Node.js/Express
app.use('/images', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
# AWS S3 बकेट पॉलिसी (CORS कॉन्फ़िगरेशन)
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedOrigins": ["*"],
"ExposeHeaders": [],
"MaxAgeSeconds": 3600
}
]
crossOrigin मान
anonymous |
क्रेडेंशियल्स (कुकीज़, HTTP ऑथ) के बिना अनुरोध; सबसे आम |
use-credentials |
क्रेडेंशियल्स के साथ अनुरोध; सर्वर को Access-Control-Allow-Credentials: true और विशिष्ट ओरिजिन भेजना होगा (वाइल्डकार्ड * नहीं) |
| (अनुपस्थित/खाली) | कोई CORS अनुरोध नहीं; कैनवास टेंटेड हो जाएगा |
पूर्ण कार्यशील उदाहरण
<!DOCTYPE html>
<html>
<head>
<title>CORS कैनवास डेमो</title>
</head>
<body>
<h2>क्रॉस-ओरिजिन छवि के साथ कैनवास</h2>
<canvas id="canvas" width="400" height="300" style="border:1px solid #ccc;"></canvas>
<br><br>
<button onclick="loadAndDraw()">छवि लोड करें और ड्रा करें</button>
<button onclick="exportImage()" disabled id="exportBtn">PNG निर्यात करें</button>
<p id="status"></p>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const status = document.getElementById('status');
const exportBtn = document.getElementById('exportBtn');
function loadAndDraw() {
status.textContent = 'छवि लोड हो रही है...';
exportBtn.disabled = true;
const img = new Image();
img.crossOrigin = "anonymous";
// एक CORS-सक्षम टेस्ट छवि
img.src = "https://via.placeholder.com/400x300/667eea/ffffff?text=CORS+Enabled";
img.onload = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
status.textContent = '✅ छवि लोड हुई और ड्रा हुई';
exportBtn.disabled = false;
};
img.onerror = () => {
status.textContent = '❌ छवि लोड विफल - CORS हेडर जांचें';
};
}
function exportImage() {
try {
const dataURL = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = 'canvas-export.png';
link.href = dataURL;
link.click();
status.textContent = '✅ छवि निर्यात की गई!';
} catch (e) {
status.textContent = '❌ निर्यात विफल: ' + e.message;
}
}
</script>
</body>
</html>
सामान्य समस्याएँ और समाधान
| CDN पर नियंत्रण नहीं | प्रॉक्सी सर्वर के माध्यम से छवि सर्व करें जो CORS हेडर जोड़ता है |
| स्थानीय फ़ाइल (file://) | CORS file:// पर काम नहीं करता; लोकल सर्वर उपयोग करें (VS Code Live Server, python -m http.server) |
| टेंटेड कैनवास रीसेट करना | कैनवास को पुनः बनाएँ: canvas.width = canvas.width या नया कैनवास तत्व |
| डेटा URL छवियाँ | data: URL क्रॉस-ओरिजिन नहीं होते; टेंट नहीं करते |