Boplo.ir
rss

من در Facebook


جستجو


آخرین مطالب

مطالب همینجوری

بر و بچ

MyView TakhteShasi Tween

دوستشون دارم

بیلبورد

دامین برای فروش: CleanCode.ir
FastFeed.ir
Fonvi.com

تماس


انواع و اقسام سفارشات طراحی و برنامه نویسی سایت پذیرفته میشه. از سایت حمایت از خرگوشهای صورتی گرفته تا سایت قاچاق اعضای بدن!
تماس

 

از بيماران سرطاني حمايت كنيم

A new begining
AHHP presents

 

آدرس کوتاه: http://Boplo.ir/:78

JSON و JSONP
۱۶ اردیبهشت ۱۳۸۹ ساعت ۱۲:۳۹

طراحی وب
معرفی JSON و JSONP که چی هستند و به چه درد میخورند
json and jsonp

مقدمه:
"اطلاعات" دارای ماهیت فیزیکی نیست و هر روشی برای نگهداری و انتقالش قراردادی است. در فضای وب هم برای انتقال اطلاعات روشهایی قرارداد شده که اگر مبدا یا فرستنده اطلاعات رعایت کنه، مقصد یا گیرنده کاملا میتونه درکش کنه.

نمونه: من یه لیست از دانش آموزهای یک کلاس دارم به همراه نمره اشون. می خوام به تو بدم که ببینی.
چند مدل می تونم این لیست رو درست کنم؟ یک مدل اینه که اسم هرکس رو می نویسم و نمره اش رو جلوش می نویسم و اسم بعدی در خط بعدی (مثل لیست نمراتی که هممون سراغ داریم). یک مدل اینه که همه رو پشت سر هم می نویسم یعنی اسم دانش آموز، بلافاصله نمره اش، یک نقطه و اسم بعدی. یک مدل دیگه اینکه یه فرمول اختراع می کنم و لیست رو براساس اون فرمول میچینم که لیستم به یک چیز عجیب غریب و غیرقابل فهم تبدیل میشه و برای اینکه بفهمم فلان دانش آموز نمره اش چنده باید از طریق همون فرمول عمل کنم. و ....
نمیشه گفت چند تا راه برای این کار وجود داره. ولی همه از لیست مدل زیرهم استفاده می کنند چون طبق یک قرارداد نانوشته است و همه ازش سر درمیارند.

در دنیای کامپیوتر هم، انتقال اطلاعات واقعا مهم و حیاتیه و نیاز به قراردادهای اینچنینی کاملا لازمه. یه سری آدم نسبتا بیکار دور هم جمع میشن و فرمتهایی رو پیشنهاد و تعریف و معرفی می کنند تا همه ازشون استفاده کنند. از معروفترین فرمتهای انتقال اطلاعات در وب XML و JSON هست.


اگر نمی دونی XML دقیقا چیه:
HTML یک فرمت خوب برای دسته بندی متن بوده و با ایده گرفتن ازش، فرمت XML رو پیشنهاد کردند که مخفف Xtendable Hypertext Language یعنی زبان نشانه گذاری توسعه یافته است. اومدند گفتند که اطلاعات رو توسط تگهایی شبیه HTML مرتب کنیم. مثلا می خوایم لیست دانش آموزها رو با فرمت XML بسازیم:

<xml>
	<studentsdata>
		<classdata>
			<name>A1</name>
			<teacher>Mr. Folani</teacher>
		</class>
		<list>
			<student>
				<firstname>Amir</firstname>
				<lastname>Hossein</lastname>
				<score>18</score>
			</student>
			
			<student>
				<firstname>Amir Hossein</firstname>
				<lastname>Hodjati</lastname>
				<score>19</score>
			</student>
			
			<student>
				<firstname>Amir Hossein</firstname>
				<lastname>Hodjati Pour</lastname>
				<score>20</score>
			</student>
		</list>
	</studentsdata>
حالا این چه فایده ای داره؟ فایده اش اینه که من اگر هزار تا لیست اینجوری داشته باشم، می تونم توسط فرمتی که دارم استفاده می کنم، اطلاعاتش رو بازیابی کنم. مثلا اینجا اطلاعات همه دانش آموزها داخل تگ list قرار گرفته. اطلاعات کلاس داخل تگ classdata، اطلاعات هر دانش آموز داخل تگ student و به همین ترتیب. این رو من خودم می دونم و میفهم و می تونم واسه هرکس دیگه ای تو همین دو خط توضیح بدم تا بفهمه.
لازم به گفتن هست RSS فرمتی استاندارد برای داده های سایته، توسط XML ولی با تگهای مشخص. یعنی توی RSS تگ title باید حاوی عنوان مطلب باشه تا همه بتونن بازیابیش کنند. کلی قصه گفتم که فایده این فرمتها رو بگم. از بین چنین فرمتهایی (که تعدادشون کم نیست)، JSON یک نمونه خیلی خاص می تونه باشه.


JSON مخفف JavaScript Object Notation است یعنی نشانه گذاری توسط اشیاء جاوااسکریپت. JSON در واقع شیء و آرایه جاوااسکریپت هست که وقتی متن رو به اون شکل مرتب کنیم، در زبان جاوااسکریپت میشه دوباره به Object یا شیء تبدیل کرد و استفاده کرد. مثلا می خوایم اطلاعات XML بالا رو به JSON تبدیل کنیم:

{
	classdata: {
		name: "A1",
		teacher: "Mr. Folani"
	},
	list: [
		{
			firstname: "Amir",
			lastname: "Hossein",
			score: "18"
		},
		{
			firstname: "Amir Hossein",
			lastname: "Hodjati",
			score: "19"
		},
		{
			firstname: "Amir Hossein",
			lastname: "Hodjati Pour",
			score: "20"
		}
	]
}
من اطلاعاتم رو به این شکل می نویسم و می تونم بین اسکریپتهام و زبانهای برنامه نویسی ام منتقل کنم. مثلا وقتی این متن که از XML کم حجمتره رو به جاوااسکریپت میبرم و در متغیری به نام data ذخیره می کنم، اینجوری می تونم پردازشش کنم:
var json = eval("(" +data+ ")");
var className = json.classdata.name;
var teacher = json.classdata.teacher;
var firstStudent_score = json.list[0].score;

خوبی JSON اینه فقط توی جاوااسکریپت قابل استفاده نیست و خیلی از زبانها ازش پشتیبانی می کنند. مثلا همین تکه کد بالا در PHP5 به این شکل میشه:

$json = json_decode($data);
$className = $json->classdata->name;
$teacher = $json->classdata->teacher;
$firstStudent_score = $json->list[0]->score;

من وقتی بین اسکریپتهام انتقال اطلاعات زیاد دارم، بجای آرایه از JSON استفاده می کنم و برای AJAX، اگر اطلاعاتم متن ساده نباشه، همیشه JSON رو به XML ترجیح میدم چون کار کردن باهاش در جاوااسکریپت خیلی سادست.


و اما JSONP،
محدودیتی در استفاده از AJAX وجود داره و اون عدم دسترسی به اطلاعاتی هست که از یک آدرس دیگه اومده. مثلا من میخوام در سایتم پیش بینی وضعیت آب و هوا رو از سایت یاهو بصورت AJAX داشته باشم. روشهایی برای این کار وجود داره ولی روش مستقیم ممکن نیست که من Request رو به سایت یاهو بفرستم و Response بگیرم. برای چنین استفاده هایی، JSONP معرفی شده.

JSONP مخفف JOSN with Padding یعنی استفاده از JSON با واسطه است (این ترجمه مفهومی اش هست نه لغوی) و در واقع یک حقه و ترفنده که با همکاری سایت مبدا و مقصد انجام میشه. به این ترتیب که مثلا من میخوام دمای تهران رو از سایت یاهو بگیرم که به شکل JSON زیر این اطلاعات رو میده و از JSONP پشتیبانی می کنه:

{
	city: "Tehran",
	temperature: "27",
	scale: "Celsius"
}
حقه به این صورت انجام میشه که من یک تابع جاوااسکریپت در صفحه میسازم که این شیء رو بصورت پارامتر میگیره. مثلا تابع زیر:
function getTemp(jsonp) {
	alert( jsonp.temperature );
}

اصل کار اینجوری انجام میشه که سایت مبدا (همون آب و هوای یاهو)، نام این تابع رو میگیره و این خروجی رو میده:

getTemp({
	city: "Tehran",
	temperature: "27",
	scale: "Celsius"
});
حالا تصور کن که من این سایت رو توسط تگ script فراخوانی کرده باشم یعنی شبیه این:
<script type="text/javascript">
	function getTemp(jsonp) {
		alert( jsonp.temperature );
	}
</script>
<script type="text/javascript"
	src="http://weather.yahoo.com/tehran/?callback=myTemp">
</script>
من توی src فرضی بالا، نام تابع رو به آدرسی که قراره JSON رو بده ارسال می کنم و خروجی این آدرس به شکل جاوااسکریپت فورا اجرا میشه و من دمای تهران رو میبینم.

کد زیر دقیقا مثل کد بالا عمل می کنه با این تفاوت که در کد زیر، JSON رو بصورت استاتیک خودمون داریم میدیم و در بالا داره بصورت داینامیک از یک سایت Extrenal میاد:

<script type="text/javascript">
	function getTemp(jsonp) {
		alert( jsonp.temperature );
	}
</script>
<script type="text/javascript">
	getTemp({
		city: "Tehran",
		temperature: "27",
		scale: "Celsius"
	});
</script>
همونطور که واضحه سایت مبدا باید JSONP رو پشتیبانی کنه یعنی نام تابع من رو بگیره و خروجی JSON خودش رو به تابع من بده.

حالا این چه ربطی به AJAX داشت؟ ما می تونیم در کدهای مربوط به AJAX، تگ script رو بسازیم، اجرا کنیم، خروجی بگیریم. کاملا شبیه AJAX. این سناریو رو فرض کن که توی سایتت، یک بخش آب و هوا داری. کاربر شهر رو انتخاب می کنه و تو دما رو توسط کد و آدرس فرضی زیر نمایش میدی:

function getTemp(jsonp) {
	alert( jsonp.temperature );
}

function getCity(city) {
	var script = document.createElement('script');
	script.type ="text/javascript";
	script.src = "http://weather.yahoo.com";
	script.src += "/" +city+ "/?callback=getTemp";
	// http://weather.yahoo.com/shiraz/?callback=getTemp
	document.getElementsByTagName('head')[0].appendChild(script);
}

خلاصه کار کردن با JSON خیلی لذتبخشه و من واقعا دوستش دارم!



پی نوشت: یکی دوستان به نام eAmin که من ایشون رو از سایت Barnamenevis.org میشناسم. به یکی از نکته های جاافتاده اشاره کردند که خوب دونستم با قدردانی از ایشون، اینجا بهش اشاره کنم:
من گفتم برای decode کردن JSON در جاوااسکریپت میتونیم از تابع eval استفاده کنیم و این توابع همه کدهای جاوااسکریپت رو اجرا می کنه! این یعنی برای گرفتن JSON باید کاملا حواسمون به ورودی های ناخواسته و مخرب باشه و بهتره که بجای تابع Eval از توابع استاندارد و مطمئن استفاده کنیم.
در سایت JSON.org می تونی توابع استاندارد تحت زبانهای مختلف و اطلاعات بیشتر کسب کنی.

 

تو چی فکر می کنی؟


eAmin : من معمولا از هرکسی تعریف نمی کنم، این خیلی خوبه که توی وبلاگتون در رابطه با هرچیزی که می خواید مطلبی بنویسید، خیلی خوب اون رو توضیح می دید و از تمامی جنبه ها بهش نگاه می کنید!
و من این قابلیت شما رو تحسین می کنم :)
----
این رو هم من اضافه کنم که JSON و مخصوصا در JSONP همیشه باید موارد امنیتی رو رعایت کرد و جلوی داده های خطرناک رو گرفت، هیچ وقت به تنهایی از eval برای انکود کردن داده ها استفاده نکنید.
از اسکریپتی که در وبسایت JSON قرار داده شده برای انکود و دکود کردن داده ها استفاده کنید و یا تابع اختصاصی امن تر از اون برای خودتون بنویسید.

موفق باشید.
(1 سال و 8 ماه و 29 روز و 7 ساعت و 14 دقیقه پیش)

alireza : salam
matlabe jalebi bood tashakor
(10 ماه و 22 روز و 6 ساعت و 42 دقیقه پیش)

Sepehr : ممنون.
(10 ماه و 8 روز و 7 ساعت و 42 دقیقه پیش)

نیما : من از طریق جستجو سر از اینجا در آورد و مدل توضیح دادنت را خیلی دوست دارم گفتم بدون تشکر از اینجا نرفته باشم

مطمئن هستم که باز به اینجا سر میزنم بوکمارک شدی :)
(8 ماه و 18 روز و 22 ساعت و 28 دقیقه پیش)

حمید : این هم فایل جاوا اسکریپت برای پردازش امن !
http://json-sans-eval.googlecode.com/files/json-minified.js
نمونش هم :
var myJson = '{ "x": "Hello, World!", "y": [1, 2, 3] }';
var myJsonObj = jsonParse(myJson);
alert(myJsonObj.x); // alerts Hello, World!
(7 ماه و 28 روز و 10 ساعت و 51 دقیقه پیش)

mrk : بنام خدا
سلام.
ممنون از مطلب مفیدتان.
یا علی مدد
(7 ماه و 27 روز و 4 ساعت و 36 دقیقه پیش)

nasrin : tashakor
(7 ماه و 21 روز و 7 ساعت و 43 دقیقه پیش)

kordestan : سلام واقعا خسته نباشی میگم
وب گردی میکردم مطالبه تو دیدم خوشم امد مثل اب خوردن بود درک و گرفتنش
زنده باشی(یاشاسین)(بژی)
(5 ماه و 13 روز و 23 ساعت و 20 دقیقه پیش)

یک دوست : با سلام شما تابع "myTemp" را بعنوان کال-بک به آدرس مورد نظر معرفی کردین ولی نام تابعی که ساختین "getTemp" هست!
(5 ماه و 13 روز و 13 ساعت و 2 دقیقه پیش)

امیرحسین : ممنون. اصلاح شد.
(5 ماه و 13 روز و 12 ساعت و 27 دقیقه پیش)

مشهدی : عالی بود!
(4 ماه و 5 روز و 12 ساعت و 24 دقیقه پیش)

ati : سلام مرسی از توضیحات تون ولی من کد بالا رو امتحان کردم و وقتی می خوام external بگیرم هیچ جوابی نمی گیرم.
لازم به ذکر من از ?callback=getTemp استفاده کردم
خوشحال میشم اشکال کار و بگید
(3 ماه و 13 روز و 23 ساعت و 55 دقیقه پیش)

امیرحسین : چون کد بالا نمونه‌ست و واقعی نیست!
(3 ماه و 13 روز و 23 ساعت و 36 دقیقه پیش)

ati : من اخه دقیقا همین مشکل و دارم یعنی اینکه می خوام بصورت داینامیک از یک سایت Extrenal، محتویاتشو (یعنی تمام <body>) رو بیارم توی page خودم.
این دو سایت توی domain مختلف هستند.
از پیگیری تون ممنونم
(3 ماه و 13 روز و 22 ساعت و 36 دقیقه پیش)

امیرحسین : اگر اون سایت با Cross Domain Request یا JSONP اجازه‌ی دسترسی رو نده، در PHP با cURL یا Socket میتونید کل محتویات یک صفحه رو بگیرید و body رو توش پیدا کنید
(3 ماه و 13 روز و 21 ساعت و 1 دقیقه پیش)

 

me

امیرحسینم. اسمم رو دوست دارم، خودم رو دوست دارم. تهران زندگی می کنم. فارغ التحصیل مهندسی صنایع هستم. برنامه‌نویسی و طراحی وب می کنم. در واقع Web Developer محسوب میشم. برنامه نویسی و وقت گذرونی با وب تنها کاریه که خسته ام نمی کنه.
آدم خیلی سردی هستم، اینو دور و وری هام میگن. ولی به نظر خودم سرد نیستم در واقع گرمای خودم رو کم بروز می دم! آدما رو اغلب دوست دارم غیر از اون مواقعی که اونا من رو نادیده میگیرن!

این سایت رو بعد از کلی اینور اونور دوباره راه انداختم تا هرچی دوست دارم توش بنویسم، چه کسی بخونه چه نخونه.
خلاصه اینجا خونه منه،

به خونه امیرحسین خوش اومدی...

MODx | Template World