অবশ্যই! আপনার দেওয়া ড্রাফটের উপর ভিত্তি করে, একটি সহজ এবং প্রাঞ্জল ভাষায় ব্লগ পোস্ট নিচে দেওয়া হলো।
শিরোনাম: ইমেজ ফেচ করতে গিয়ে JSON পার্সিং এরর? চলুন জানি বাইনারি ডেটা হ্যান্ডলিং এর রহস্য
আপনি একজন ওয়েব ডেভেলপার। একটি API থেকে ডেটা fetch
করছেন, সবকিছু ঠিকঠাকই চলছিল। কিন্তু হঠাৎ করে ব্রাউজার কনসোলে একটি অদ্ভুত এরর দেখতে পেলেন:
Uncaught (in promise) SyntaxError: Unexpected token '�', "���� Exif"... is not valid JSON
এই ধরনের এরর দেখলে ঘাবড়ে যাওয়াটাই স্বাভাবিক। এর মানে কী? কেন এটি হলো? এবং সবচেয়ে গুরুত্বপূর্ণ, এর সমাধান কী?
আজকের পোস্টে আমরা এই সমস্যাটির গভীরে যাব এবং জানব কিভাবে ব্রাউজারে বাইনারি ডেটা (যেমন: ছবি বা ভিডিও) আসে, কেন আসে এবং জাভাস্ক্রিপ্ট ব্যবহার করে সঠিকভাবে তা হ্যান্ডেল করতে হয়।
সমস্যাটা আসলে কী?
প্রথমেই এরর মেসেজটি বোঝার চেষ্টা করি। SyntaxError: ... is not valid JSON
অংশটি বলছে যে, আপনার কোড একটি JSON ডেটা পাবে বলে আশা করেছিল, কিন্তু যা পেয়েছে তা বৈধ JSON নয়। আর Unexpected token '�'
অংশটি ইঙ্গিত দিচ্ছে যে, কোডটি এমন কিছু ডেটা পেয়েছে যা সে টেক্সট হিসেবে পড়তে পারছে না। Exif
শব্দটি একটি বড় সূত্র, কারণ এটি সাধারণত ছবির মেটাডেটার সাথে যুক্ত থাকে।
এর মানে হলো, আপনার fetch()
কলটি একটি API এন্ডপয়েন্ট থেকে ডেটা আনার চেষ্টা করছে, যেখান থেকে সার্ভার আসলে বাইনারি ডেটা (এই ক্ষেত্রে একটি ছবি) পাঠাচ্ছে, কিন্তু আপনার কোড সেই ডেটাকে JSON হিসেবে পার্স বা প্রসেস করার চেষ্টা করছে।
উদাহরণস্বরূপ, আপনি হয়তো এমন একটি এন্ডপয়েন্টে fetch
করছেন যা ছবি জেনারেট করে:
https://pollinations.ai/p/Bird%20Fly%20in%20the%20sky?seed=3878
এই URL-টি সরাসরি একটি ছবি রিটার্ন করে, কোনো JSON অবজেক্ট নয়।
কেন এই ভুলটি হয়?
সাধারণত এই ভুলটি ঘটে যখন আমরা fetch
করার পর response.json()
মেথডটি ব্যবহার করি। যেমন:
fetch("https://pollinations.ai/p/...")
.then((response) => response.json()) // 🚫 ভুল: এখানে সমস্যাটি হচ্ছে
.then((data) => {
// ... কোড
});
response.json()
মেথডটি সার্ভার থেকে আসা ডেটাকে টেক্সট হিসেবে ধরে নেয় এবং তাকে JSON অবজেক্টে রূপান্তর করার চেষ্টা করে। কিন্তু সার্ভার যখন ছবি বা ভিডিওর মতো বাইনারি ডেটা পাঠায়, তখন response.json()
সেই বাইনারি ডেটাকে টেক্সট হিসেবে পড়তে পারে না এবং এরর দেয়।
সঠিক সমাধান কী?
যখন আমরা জানি যে সার্ভার থেকে বাইনারি ডেটা (ছবি, ভিডিও, পিডিএফ ইত্যাদি) আসবে, তখন আমাদের response.json()
এর পরিবর্তে response.blob()
ব্যবহার করতে হবে।
Blob কী? Blob (Binary Large Object) হলো একটি ফাইল-সদৃশ অবজেক্ট যেখানে অপরিবর্তনশীল, র' বাইনারি ডেটা স্টোর করা হয়। ছবি, ভিডিও বা যেকোনো ফাইল হ্যান্ডেল করার জন্য এটি খুবই উপযোগী।
সঠিক পদ্ধতি:
fetch
ব্যবহার করে ডেটা আনুন।response.blob()
ব্যবহার করে রেসপন্সকে একটি Blob অবজেক্টে রূপান্তর করুন।URL.createObjectURL(blob)
ব্যবহার করে ঐ Blob অবজেক্টের জন্য একটি অস্থায়ী URL তৈরি করুন।- এই URL-টি একটি
<img>
ট্যাগেরsrc
অ্যাট্রিবিউটে ব্যবহার করে ছবিটি প্রদর্শন করুন।
প্লেইন জাভাস্ক্রিপ্টে কোড উদাহরণ:
fetch("https://pollinations.ai/p/Bird%20Fly%20in%20the%20sky?seed=3878")
.then((response) => response.blob()) // ✅ সঠিক: রেসপন্সকে বাইনারি ব্লব হিসেবে পার্স করুন
.then((blob) => {
const imageUrl = URL.createObjectURL(blob);
// এখন এই imageUrl টি একটি img ট্যাগে ব্যবহার করা যাবে
document.getElementById("myImage").src = imageUrl;
});
এবং আপনার HTML ফাইল:
<img id="myImage" alt="Generated image" />
React অ্যাপে কিভাবে ব্যবহার করবেন?
React-এ কাজটি আরও সহজ এবং সুন্দরভাবে করা যায় useState
এবং useEffect
হুক ব্যবহার করে।
import React, { useState, useEffect } from "react";
const ImageFetcher = () => {
const [imageUrl, setImageUrl] = useState("");
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchImage = async () => {
try {
const response = await fetch(
"https://pollinations.ai/p/Bird%20Fly%20in%20the%20sky?seed=3878"
);
if (!response.ok) {
throw new Error("Network response was not ok");
}
const blob = await response.blob();
const url = URL.createObjectURL(blob);
setImageUrl(url); // React state এ ইমেজ URL সেট করুন
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchImage();
// ক্লিন-আপ ফাংশন: কম্পোনেন্ট আনমাউন্ট হলে মেমোরি থেকে URL টি রিলিজ করে দেওয়া ভালো
return () => {
if (imageUrl) {
URL.revokeObjectURL(imageUrl);
}
};
}, []); // খালি dependency array মানে এই ইফেক্টটি শুধু একবার রান করবে
if (loading) return <p>Loading image...</p>;
if (error) return <p>Error: {error}</p>;
return (
<img src={imageUrl} alt="Generated image" style={{ maxWidth: "100%" }} />
);
};
export default ImageFetcher;
সারসংক্ষেপ
আসুন মূল বিষয়টি আরেকবার ঝালিয়ে নেই:
- ❌ ভুল পদ্ধতি:
response.json()
ব্যবহার করা, যখন সার্ভার বাইনারি ডেটা পাঠায়। এটি শুধু টেক্সট-ভিত্তিক JSON ডেটার জন্য প্রযোজ্য। - ✅ সঠিক পদ্ধতি:
response.blob()
ব্যবহার করা। এটি ছবি, ভিডিও বা যেকোনো ফাইলের মতো বাইনারি ডেটা হ্যান্ডেল করার জন্য সঠিক উপায়।
আশা করি, এই পোস্টটি পড়ার পর আপনি বাইনারি ডেটা হ্যান্ডেল করার ক্ষেত্রে আরও বেশি আত্মবিশ্বাসী হবেন এবং Unexpected token '�'
এররটি দেখলে আর ভয় পাবেন না। হ্যাপি কোডিং! 🚀