لیست شهرها و استان‌های ایران

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

به روزرسانی ۹ اسفند ۹۴
فهرست جدیدی از سایت مرکز آمار ایران استخراج شد و جایگزین فهرست قبلی شد که ظاهرا اشکال‌هایی در آن وجود داشت.
فهرست شهر و استان ها مربوط به سال ۱۳۹۳ است. در صورتی که فهرست جدیدتری در این سایت قرار بگیرد، در اولین فرصت به روزرسانی خواهد شد.

فهرست شهر‌ها و استان‌های ایران – اینجا کلیک کنید

ارسال شده در برنامه‌نویسی, جاوااسکریپت, عمومی, پایگاه داده | برچسب‌شده , , | ۹ دیدگاه

یک سایت مورد حمله از روش SQL Injection

قرار بر این شد که سایتی را که قبلا با ابزارهای مایکروسافتی توسعه پیدا کرده بود و مورد حمله‌ی SQL Injection بود، بازطراحی و بازنویسی کنیم. نخستین مشکل این بود که سایت از نظر اندازه جزء سایت‌های متوسط به شمار می‌رود و بازطراحی آن به زمان قابل توجهی نیازمند بود. بنابراین اولویت نخست این بود که سایت فعلی به شکلی قابل قبول برگردد و جلوی حملات آتی هم گرفته شود تا مقداری فرصت برای کار جدید فراهم شود.
در این مسیر با مشکلات متعددی مواجه شدیم که پیدا کردن و رفع کردن آن حاوی تجربیات خوبی بود.

مشکل اول: عدم دسترسی به توسعه‌دهندگان اصلی و کد بودن سورس سایت

به دلیل اینکه سورس سایت کدشده بود، امکان پیدا کردن و مسدود کردن اشکال موجود تقریبا ناممکن بود. بنابراین تلاش شد، با روش‌های مختلف امکان دسترسی به صفحات حاوی فرم مسدود شود که آن هم بی‌نتیجه بود.
نخستین تجربه: هنگامی که سایتی جدید سفارش می‌دهید، در اختیار داشتن سورس سایت، ممکن است در آینده موضوعی حیاتی به شمار برود.

مشکل دوم: دسترسی به بانک اطلاعاتی

شرکتی که خدمات میزبانی سایت را بر عهده داشت، سیستم فنی و پاسخگویی چندان شناخته شده‌ای را در اختیار قرار نمی‌داد. پیدا کردن مسیر ارتباطی برای اتصال به پایگاه داده SQL Server حدود ۲ روز زمان را از بین برد.
تجربه‌ی دوم: انتخاب صحیح ابزارهای توسعه، سیستم میزبانی وب و نگهداری اطلاعات مهم در این موارد، موضوعی مهم است.

مشکل سوم: پیدا کردن و بازگرداندن اطلاعات تخریب شده

برای پیدا کردن رشته‌های مورد نظر در تمام جدول‌ها و فیلدهای پایگاه داده از اسکریپتی که در این صفحه قرار دارد استفاده شد.
تغییر دادن گروهی ردیف‌های پایگاه داده نیز، با کمک عبارت‌های منظم و تولید کوئری‌هایی روی داده‌های کپی شده از جداول به انجام رسید.
حمله کنندگان ظاهرا با استفاده از اسکریپتی به صورت دائم در حال ارسال اطلاعات مخرب درون وبسایت بودند، پس از اینکه با زحمت فراوان، ساختار نه چندان منظم بانک اطلاعاتی رمزگشایی و اصلاح شد، در زمان کوتاهی تمام زحمات بر باد رفت و سایت به وضعیت قبلی برگشت.
تجربه‌ی سوم: پیش از اصلاح سایت هک شده، ابتدا مسیرهای حمله را شناسایی و مسدود کنید.

مشکل چهارم: مسدود کردن مسیرهای حمله

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

جمع بندی نهایی: چنانچه قصد پیاده‌سازی محصولی نرم‌افزاری را دارید، اگر در این زمینه تخصصی ندارید، حتما از یک مشاور خبره برای ارزیابی پیمانکاران و راه حل‌های آنان استفاده کنید. ممکن است خسارت‌های ناشی از عدم انجام این کار به مراتب بیش از هزینه‌های استفاده از یک مشاور باشد.

ارسال شده در امنیت, برنامه‌نویسی, عبارت‌های منظم, پایگاه داده | برچسب‌شده , , , | دیدگاه‌تان را بنویسید

قراردادن چند کد امنیتی reCaptcha در یک صفحه

برای آشنایی با reCaptcha اینجا کلیک کنید

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

فعال‌سازی reCaptcha به صورت ضمنی( Implicit ) یا اتوماتیک حاوی این محدودیت است و هنگام فعال‌سازی تنها اولین فیلد حاوی کد امنیتی فعال سازی می‌شود
ادامه‌ی خواندن

ارسال شده در برنامه‌نویسی, جاوااسکریپت, عمومی | برچسب‌شده , , , | دیدگاه‌تان را بنویسید

پردازش تعداد زیاد ردیف‌های پایگاه داده در لاراول

در بسیاری مواقع به ویژه در هنگام تهیه‌ی گزارش‌ها ممکن است لازم شود، تمامی ردیف‌های یک یا چند جدول از پایگاه داده پیمایش شوند و برخی محاسبات به وسیله‌ی کد به انجام برسند.
فریم‌ورک لاراول برای انجام این کار دستور chunk را تعبیه کرده است که ردیف‌های جدول را در بسته‌هایی با اندازه‌ی دلخواه واکشی می‌کند.
این دستور در تعداد ردیف‌های نه چندان زیاد قابل استفاده است ولی چنانچه تعداد ردیف‌ها از حدی بیشتر شود، به علت اینکه دستور chunk به ازای هر بسته از ردیف‌ها یک query با استفاده از limit را اجرا می‌کند، هر چه تعداد بسته‌های داده بیشتر باشد، سرعت واکشی از پایگاه داده نیز کاهش پیدا می‌کند و در عمل استفاده از آن غیرقابل توجیه خواهد شد.
ادامه‌ی خواندن

ارسال شده در PHP, برنامه‌نویسی, عمومی, پایگاه داده | برچسب‌شده , , , , | دیدگاه‌تان را بنویسید

آشنایی با CORS یا Cross-origin resource sharing

HTTP access control (CORS)

CORS کوتاه‌شده‌ی عبارت Cross-origin resource sharing است. محل کاربرد CORS در مرورگرهای مدرن و برای بررسی اجازه‌ی دسترسی از راه دور به منابع و سرویس‌های تحت وب است.
برای مثال در حالت عادی امکان استفاده از فایل‌های فونت از روی یک سرور دیگر وجود ندارد یا امکان ارسال یک درخواست AJAX از روی دامنه‌ای غیر از دامنه‌ی فعلی ناممکن است.CORS ابزاری است که روشی برای حذف این محدودیت در اختیار برنامه‌نویسان قرار می‌دهد.
ادامه‌ی خواندن

ارسال شده در HTML, امنیت, برنامه‌نویسی, عبارت‌های منظم, فناوری, لاراول | برچسب‌شده , , | ۹ دیدگاه

ایجاد کننده اسکریپت درج والد و فرزند در پایگاه داده MySQL

برای یکی از پروژه‌های در دست انجام لازم بود تا حجم زیادی از جدول‌ها و اطلاعات را به شکل والد و فرزند در سیستم درج کنم.
اطلاعات در یک فایل اکسل قرار گرفته بود که درج آن‌ها بدون یک ابزار که کار را سرعت ببخشد، حتی با عبارت‌های منظم هم کاری زمان‌بر و دشوار بود و احتمال اشتباه در آن بسیار بالا می‌رفت
بنابراین یک ابزار ساده درست کردم که کار درج اطلاعات را با ایجاد اسکریپت SQL در جدول‌های پایگاه داده آسان‌تر کند.
برای نمونه: فهرست استان‌ها و شهر‌های هر استان باید در دو جدول مختلف وارد شوند. جدول شهرها می‌بایست، یک کلید خارجی به جدول استان‌ها داشته باشد تا مشخص شود هر شهر در کدام استان قرار گرفته است.
به این منظور، نام هر استان و شهرهای قرار‌گرفته در آن استان را زیر هم داخل یک فایل متنی قرار می‌دهیم و بین هر گروه از استان‌ها، یک خط خالی قرار می‌دهیم.
مرحله‌ی بعدی، مشخص کردن نام جدول والد( استان‌ها ) و فرزند( شهرها ) است. همچنین نام ستون کلید خارجی قرار گرفته در جدول فرزند( شهرها ) الزامی است.

برای استفاده‌ی آنلاین از این ابزار، اینجا کلیک کنید

ارسال شده در HTML, نرم‌افزار | برچسب‌شده , , , | ۳ دیدگاه

هفت نکته‌ی مهم SEO در سال ۲۰۱۹

سئو ۲۰۱۵

همزمان با سپری شدن زمان، الگوریتم‌های رتبه‌بندی سایت‌ها توسط موتورهای جستجو نیز در حال تحول و بهبود مداوم هستند، انجام SEO یا بهینه‌سازی موتورهای جستجو، نیز نیازمند فرآیندهای متفاوتی نسبت به گذشته است.
آنچه در ادامه مشاهده می‌کنید، فهرستی از آخرین روش‌های بهبود SEO هستند.
ادامه‌ی خواندن

ارسال شده در SEO | برچسب‌شده , , | دیدگاه‌تان را بنویسید

اعتبارسنجی فیلدهای متنی برای حروف فارسی با استفاده از jQuery

همان گونه که می‌دانید، اعتبارسنجی عبارت‌های واردشده توسط کاربر باید در سمت سرور به انجام برسند، با این حال برای بهبود تجربه‌ی کاربری ممکن است بخواهیم اعتبارسنجی ورودی‌های کاربر را علاوه بر سمت سرور، در سمت مشتری نیز به انجام برسانیم.
در قطعه کد دنباله، روشی ساده برای اعتبارسنجی فیلدهای input از نوع text یا هر نوع متنی دیگر برای ورود حروف فارسی ارائه می‌شود:

$( 'body' ).on( 'keypress', 'input.persian', function( e ) {
	// backspace, delete, tab, escape, enter
	if ( $.inArray(e.keyCode, [ 46, 8, 9, 27, 13 ]) !== -1 ||
		 // Ctrl+A
		( ( e.charCode == 65 || e.charCode == 97 ) && e.ctrlKey === true ) || 
		 // home, end, left, right
		( e.keyCode >= 35 && e.keyCode <= 39 ) ) {
			 return;
	}
 
	if ( -1 == $.inArray( String.fromCharCode( e.charCode ), ['‌', ' ', 'آ','ا','ب','پ','ت','ث','ج','چ','ح','خ','د','ذ','ر','ز','ژ','س','ش','ص','ض','ط','ظ','ع','غ','ف','ق','ک','گ','ل','م','ن','و','ه','ی','ي','ك','ة'] ) ) {
		e.preventDefault();
	}
 
} );

برای استفاده از این قطعه کد، می‌بایست آن را در ابتدا یا انتهای فایل html خود فراخوانی کنید.
پس از فراخوانی این کد، تمامی inputهایی که صفت class آن‌ها مقدار persian را داشته باشد، به صورت خودکار ارزیابی می‌شوند.

<input class="persian" name="fname" type="text" />
<input class="persian" name="lname" type="text" />

این تابع به صورت delegate تعریف شده است. بنابراین تمامی فیلدهای متنی که پیش از اجرای دستور یا پس از آن ایجاد شوند، ارزیابی می‌شوند.
به علت تعریف این قطعه کد به صورت delegate، کارایی این روش بسیار بالا است و در تعداد زیاد input هم اثر اندکی روی کارایی سایت ایجاد خواهد کرد.

ارسال شده در جاوااسکریپت, عمومی | برچسب‌شده , , , , | ۲ دیدگاه

آشنایی با Zepto.js به عنوان جایگزینی برای jQuery

Zepto.js یک کتابخانه‌ی سمت مرورگر است که می‌تواند در برخی کاربردها جایگزین مناسبی برای jQuery باشد. مهم‌ترین ویژگی Zepto، سازگاری ساختار این کتابخانه با جی‌کوئری است. به این معنی که چنانچه شیوه‌ی کدنویسی با jQuery را بدانید، شیوه‌ی کدنویسی Zepto را نیز فرا گرفته‌اید.

فلسفه‌ی Zepto

این کتابخانه در ابتدا برای ایجاد ابزاری سبک برای توسعه‌ی تحت موبایل ایجاد شد. در ادامه با اضافه شدن بخش‌های دیگر و پشتیبانی از سایر مرورگرهای مدرن، اکنون به عنوان کتابخانه‌ای قابل اعتماد برای توسعه‌ی نرم‌افزارهای تحت وب به شمار می‌رود.
ادامه‌ی خواندن

ارسال شده در برنامه‌نویسی, جاوااسکریپت | برچسب‌شده , | دیدگاه‌تان را بنویسید

رویدادهای delegate در جی‌کوئری

رویدادها یا eventهای delegate رویدادهایی هستند که به عنصرهای اصلی متصل نمی‌شوند. برای مثال چنانچه یک جدول با ۱۰۰ ردیف و ۱۰ ستون داشته باشیم، و بخواهیم زمان کلیک شدن روی یک سلول از این موضوع با خبر شویم، با پیوست کردن رویداد click به عنصر table می‌توانیم از وقوع کلیک روی هر سلول باخبر شویم.

علت عملکرد رویدادهای delegate این است که اغلب مرورگرها، رویدادها را به صورت درختی منتشر می‌کنند. یعنی در هنگام کلیک روی یک عنصر td، عنصرهای tr، tbody، table و body به ترتیب از این رویداد مطلع خواهند شد.

دو سناریو برای استفاده از رویدادهای delegate به جای پیوست کردن رویدادها به تک‌تک عنصرها وجود دارد.

سناریوی نخست، زمانی است که عنصرهای داخلی، در زمان اجرا ایجاد شوند و در شروع کار وجود نداشته باشند.
در این حالت، بدون نگرانی از کاهش کارایی و خطاهای احتمالی، می‌توانیم از رویدادهای delegate استفاده کنیم.

سناریوی دوم زمانی است که تعداد عنصرهای هدف بسیار زیاد باشند و استفاده از رویدادهای delegate در این شرایط برای افزایش کارایی صورت می‌پذیرد. یک رویداد delegate در مقایسه با صدها و هزاران رویداد عادی می‌تواند اثر بزرگی در کارکرد نرم‌افزار ما به ویژه در مرورگرهای محدود مانند مرورگرهای موبایل به همراه داشته باشد.

استفاده از رویدادهای delegate در نگارش‌های مختلف jQuery به شیوه‌های مختلفی انجام می‌شود. قدیمی‌ترین روش که اکنون منسوخ شده است استفاده از دستور live است. این تابع، به صورت ضمنی، رویدادها را به عنصر body متصل می‌کند و بر اساس selector مشخص شده، رویدادهای مربوط به عنصر دلخواه شما را به تابع هدف هدایت می‌کند.

روش دوم که آن نیز در نگارش ۱.۷ جی‌کوئری منسوخ شد، استفاده از دستور delegate است. این دستور، رویداد delegate را به عنصری که شما مشخص کنید پیوست می‌کند. در نتیجه، از خطای احتمالی در دستور live زمانی که یکی از عنصرهای میانی، انتشار رویداد را متوقف کند، جلوگیری می‌شود.

در آخرین نگارش‌های jQuery پیوست کردن رویدادهای delegate همانند رویدادهای معمولی با استفاده از دستور on به انجام می‌رسد.

// jQuery.on( events [, selector ] [, data ], handler );
jQuery( 'table' ).on( 'click', 'td', tdClicked );
 
function tdClicked( evt ) {
	alert( $( this ).text() );
}

همان‌گونه که در مثال بالا مشاهده می‌کنید، رویداد تنها یک‌بار به عنصر table پیوست می‌شود ولی با هر کلیک روی عنصرهای داخلی از نوع td، رویداد به صورت delegate فراخوانی و متغیر this نیز به عنصر درونی اشاره خواهد کرد.

به یک شیوه‌ی دیگر نیز می‌توان به صورت ضمنی همین عملکرد را در اختیار داشت. در این روش، فیلتر کردن عنصرها به صورت دستی انجام می‌شود و با توجه به delegate نبودن رویداد، دسترسی به عنصر داخلی با استفاده از event.target به جای this ممکن خواهد بود:

jQuery( 'table' ).on( 'click', tableClicked );
 
function tableClicked( evt ) {
	if ( evt.target.nodeName == 'TD' ) {
		alert( $( evt.target ).text() );
	}
}
ارسال شده در برنامه‌نویسی, جاوااسکریپت | برچسب‌شده | ۲ دیدگاه