بدنه درخواست را درست نوشتهاید و کلید دسترسی هم معتبر است، اما سرور همچنان خطا برمیگرداند؟ یکی از مواردی که باید بررسی کنید، هدرهای درخواست است.
تنظیم اشتباه نوع محتوا، ارسال نادرست اعتبارنامه یا وجود هدرهای تکراری میتواند مانع پردازش صحیح درخواست شود؛ البته همه خطاهای API به هدرها مربوط نیستند.
HTTP Header دقیقاً چیست؟
هدرهای HTTP فیلدهایی هستند که اطلاعات تکمیلی را همراه درخواست یا پاسخ بین کلاینت و سرور منتقل میکنند. این اطلاعات میتوانند نوع محتوای بدنه، اعتبارنامههای احراز هویت، ترجیح کلاینت برای پاسخ یا دستورالعملهای کش را مشخص کنند.
اگر بدنه پیام را محموله اصلی در نظر بگیریم، هدر شبیه برچسبهای روی بسته است: توضیح میدهد محتوای بسته چیست و گیرنده باید چگونه با آن برخورد کند. برای مثال، متن پیامک و شماره گیرنده در بدنه درخواست قرار میگیرند، اما هدر Content-Type: application/json اعلام میکند که این بدنه با فرمت JSON ارسال شده است.
همه پیامهای HTTP بدنه ندارند؛ برای نمونه، یک درخواست GET معمولی میتواند بدون بدنه ارسال شود و همچنان هدر داشته باشد. همچنین کد وضعیت پاسخ، مانند ۲۰۰ یا ۴۰۱، با هدرهای پاسخ متفاوت است؛ هرچند ابزارهای توسعه معمولاً آنها را در یک صفحه نمایش میدهند.
ساختار هدرهای HTTP چگونه است؟
در نمایش متنی HTTP/1.1، هر هدر از نام، دونقطه و مقدار تشکیل میشود:
Content-Type: application/json
Accept: application/jsonنام هدر به بزرگی و کوچکی حروف حساس نیست؛ بنابراین Content-Type و content-type یک نام محسوب میشوند. این قاعده را به مقدار هدر تعمیم ندهید؛ برای مثال، مقدار توکن را باید دقیقاً مطابق مقدار صادرشده ارسال کنید. در HTTP/2 و HTTP/3 شکل انتقال هدرها متفاوت است، اما مفهوم نام و مقدار همچنان برقرار است.

هدر در کدام قسمت درخواست و پاسخ قرار میگیرد؟
در نمونه آموزشی زیر، خط اول متد، مسیر و نسخه HTTP را مشخص میکند. سپس هدرها میآیند و یک خط خالی، آنها را از بدنه جدا میکند. این مثال عمومی است و به API مشخصی تعلق ندارد:
POST /api/example HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
{"message":"Hello"}پاسخ فرضی همین درخواست میتواند ساختار زیر را داشته باشد. خط اول وضعیت پاسخ است، دو خط بعدی هدر هستند و JSON انتهایی بدنه پاسخ است:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{"success":true}در استفاده معمول از کتابخانههای HTTP، لازم نیست این ساختار را دستی بسازید؛ ابزار، خط شروع و جداسازی هدر از بدنه را مدیریت میکند.
هدر درخواست و پاسخ چه تفاوتی دارند؟
تفاوت اصلی به فرستنده و کاربرد هدر مربوط است. بعضی هدرها مخصوص درخواست یا پاسخ هستند و بعضی، مانند Content-Type، در هر دو کاربرد دارند.
| نوع | جهت ارسال | کاربرد و نمونه |
|---|---|---|
| هدر درخواست | از کلاینت به سرور | اعلام ترجیح پاسخ با Accept یا ارائه اعتبارنامه با Authorization |
| هدر پاسخ | از سرور به کلاینت | اعلام مقصد تغییر مسیر با Location یا تنظیم کوکی با Set-Cookie |
| هدر قابل استفاده در هر دو | بسته به پیام | Content-Type نوع محتوای بدنه همان درخواست یا پاسخ را مشخص میکند |
هدرهای درخواست یا Request Headers
کلاینت با هدرهای درخواست، اطلاعات لازم برای رسیدگی به درخواست را به سرور میدهد. برای مثال، Accept نوع محتوای ترجیحی پاسخ را اعلام میکند و Authorization در APIهایی که از آن استفاده میکنند، اعتبارنامه را منتقل میکند.
هدرهای پاسخ یا Response Headers
سرور با هدرهای پاسخ توضیح میدهد که کلاینت چگونه پاسخ را پردازش کند. برای نمونه، Content-Type نوع محتوای برگشتی را نشان میدهد و Cache-Control درباره ذخیرهسازی و استفاده مجدد از پاسخ دستور میدهد.
جدول مهمترین هدرهای HTTP در کار با وبسرویس
جدول زیر هدرهایی را نشان میدهد که شناخت آنها برای شروع کار با API مفید است. نیاز به ارسال هر هدر را مستندات سرویس و نوع درخواست تعیین میکند.
| هدر | محل استفاده | کاربرد | نمونه مقدار |
|---|---|---|---|
| Content-Type | درخواست و پاسخ | نوع محتوای بدنه همان پیام | application/json |
| Accept | درخواست | نوع محتوای قابل پذیرش برای پاسخ | application/json |
| Authorization | درخواست | اعتبارنامه مطابق روش احراز هویت سرویس | Bearer YOUR_ACCESS_TOKEN |
| Host | درخواست HTTP/1.1 | نام میزبان مقصد و در صورت نیاز پورت | api.example.com |
| User-Agent | درخواست | معرفی نرمافزار کلاینت | MyApp/1.0 |
| Content-Length | درخواست و پاسخ | طول بدنه پیام بر حسب بایت | 348 |
| Cache-Control | درخواست و پاسخ | دستورالعملهای کش | no-store |
| Location | پاسخ | معرفی مقصد تغییر مسیر یا نشانی منبع ایجادشده | https://example.com/new-path |
| WWW-Authenticate | پاسخ | اعلام شیوه احراز هویت مورد نیاز | Bearer |
تفاوت Content-Type و Accept چیست؟

Content-Type میگوید «بدنهای که همراه این پیام فرستادهام چه نوعی دارد؟» اما Accept در درخواست میگوید «چه نوع پاسخی را میتوانم دریافت کنم؟» بنابراین تنظیم Accept بهتنهایی، نوع بدنه درخواست را مشخص نمیکند.
Content-Type: application/json
Accept: application/jsonاین ترکیب یعنی بدنه درخواست JSON است و کلاینت پاسخ JSON را میپذیرد. اگر سرور نتواند نوع محتوای درخواست را بپذیرد، ممکن است خطای 415 Unsupported Media Type برگرداند. اگر نتواند پاسخی سازگار با Accept ارائه کند، ممکن است پاسخ 406 Not Acceptable بدهد؛ رفتار دقیق به پیادهسازی سرویس بستگی دارد.
برای ارسال فایل با multipart/form-data، معمولاً اجازه دهید ابزار یا کتابخانه، Content-Type و مقدار boundary را تولید کند. تنظیم دستی و ناقص این هدر میتواند باعث شکست آپلود شود.
پیشنهاد خواندنی: اگر با ساختار دادههای JSON آشنا نیستید، مقاله JSON چیست؟ را بخوانید.
هدر Authorization و محل صحیح اعتبارنامه

بسیاری از APIها اعتبارنامه را در هدر Authorization دریافت میکنند. در روش Bearer، ساختار آن به شکل زیر است؛ Bearer نام شیوه احراز هویت است، نه یک هدر جداگانه:
Authorization: Bearer YOUR_ACCESS_TOKENاما این روش برای همه APIها یکسان نیست. بعضی سرویسها کلید را در هدر اختصاصی یا بدنه درخواست دریافت میکنند. طبق مستندات ارسالی API نسخه ۴ پیامرسان، مقدار ApiKey باید داخل بدنه JSON قرار بگیرد و احراز هویت این متدها با هدر Bearer انجام نمیشود.
اعتبارنامه را مطابق مستندات سرویس ارسال کنید و آن را در URL قرار ندهید؛ آدرسها ممکن است در لاگها و ابزارهای مختلف ثبت شوند. قرارگرفتن کلید در هدر یا بدنه نیز بهتنهایی امنیت ایجاد نمیکند: از HTTPS استفاده کنید، مقادیر حساس را از لاگها حذف کنید و کلید وبسرویس پیامکی را فقط در سمت سرور نگه دارید.
پیشنهاد خواندنی: برای آشنایی با روشهای مختلف، مقاله وب سرویس احراز هویت را مطالعه کنید.
Host، User-Agent و Content-Length را چه کسی تنظیم میکند؟
هدر Host در HTTP/1.1 میزبان مقصد را مشخص میکند و برای تشخیص مقصد در سرورهایی که چند دامنه دارند کاربرد دارد. در استفاده معمول از Postman، cURL یا کتابخانههای HTTP، این مقدار از URL ساخته میشود و نیازی به تنظیم دستی ندارد.
User-Agent نرمافزار درخواستدهنده را معرفی میکند و میتواند در بررسی لاگها مفید باشد. بااینحال، مقدار آن قابل جعل است و نباید مدرک احراز هویت محسوب شود. در مرورگر، مدیریت برخی هدرها در اختیار خود مرورگر است و آزادی تنظیم آنها مانند یک برنامه سمت سرور نیست.
Content-Length نیز معمولاً توسط ابزار محاسبه میشود. آن را با تعداد کاراکترها اشتباه نگیرید؛ حروف فارسی در UTF-8 میتوانند بیش از یک بایت داشته باشند. برای جلوگیری از ناسازگاری طول بدنه، این هدر را بدون نیاز مشخص، دستی وارد نکنید.
هدرهای کش، کوکی و فشردهسازی
کاربرد هدرها به ارسال JSON و اعتبارنامه محدود نیست. این چند نمونه به درک هدرهای پاسخ کمک میکنند:
- Cache-Control: رفتار کش را کنترل میکند. برای مثال،
no-storeدستور میدهد پاسخ ذخیره نشود.no-cacheمعنای متفاوتی دارد: استفاده مجدد از نسخه ذخیرهشده باید پس از اعتبارسنجی انجام شود. - ETag: مشخصهای برای نسخه یک منبع است. کلاینت میتواند آن را در درخواست بعدی با
If-None-Matchبفرستد تا سرور درباره تغییرکردن منبع تصمیم بگیرد. - Cookie و Set-Cookie: سرور با Set-Cookie کوکی تنظیم میکند و مرورگر، در صورت مجازبودن طبق قواعد کوکی، آن را در درخواستهای بعدی با Cookie میفرستد.
- Accept-Encoding و Content-Encoding: اولی روشهای فشردهسازی قابل پذیرش کلاینت را اعلام میکند و دومی کدگذاری اعمالشده بر محتوا، مانند
gzip، را نشان میدهد. این موضوع با نوع محتوا در Content-Type متفاوت است.
هدرهای سفارشی برای محدودیت و ردیابی درخواست
بعضی سرویسها هدرهای اختصاصی دارند. برای مثال، ممکن است X-RateLimit-Limit سقف درخواست مجاز را اعلام کند یا X-Request-ID شناسهای برای پیگیری درخواست در لاگها باشد. وجود، جهت ارسال و معنای دقیق این هدرها به مستندات همان سرویس بستگی دارد.
پیشوند X- در سرویسهای موجود دیده میشود، اما برای نامگذاری فیلدهای جدید توصیه نمیشود. همچنین پس از دریافت پاسخ محدودیت نرخ، هدر Retry-After، در صورت وجود، میتواند زمان انتظار پیشنهادی سرور را مشخص کند. این نمونهها به معنای پشتیبانی قطعی API پیامرسان از این هدرها نیستند.
چطور هدرهای HTTP را در مرورگر ببینیم؟
برای مشاهده هدرهای درخواستهای یک صفحه در مرورگرهای مبتنی بر Chrome، مراحل زیر را انجام دهید:
- ابزار توسعهدهنده یا DevTools را باز کنید و وارد تب
Networkشوید. - صفحه را دوباره بارگذاری کنید یا عملی را انجام دهید که درخواست موردنظر را ایجاد میکند.
- درخواست را انتخاب کنید؛ برای یافتن درخواستهای API میتوانید از فیلتر
Fetch/XHRکمک بگیرید. - در بخش
Headers، قسمتهای Request Headers و Response Headers را بررسی کنید. بدنه ارسالی معمولاً در Payload و محتوای پاسخ در Response دیده میشود.
این ابزار فقط ارتباط مرورگر را نشان میدهد. اگر بکاند شما به وبسرویس پیامکی متصل شود، درخواست خروجی بکاند در Network مرورگر دیده نمیشود. همچنین پیش از ارسال اسکرینشات یا فایل گزارش برای پشتیبانی، توکنها، کوکیها و سایر اطلاعات حساس را حذف کنید.
چطور در Postman و cURL هدر تنظیم کنیم؟
برای تمرین، از متد GetAccountInfo در API نسخه ۴ پیامرسان استفاده میکنیم. طبق مستندات ارسالی، این متد اطلاعات اعتبار و خطهای حساب را برمیگرداند و پیامک ارسال نمیکند. درخواست آن POST است و ApiKey را در بدنه JSON دریافت میکند.
تنظیم هدر و بدنه در Postman
- یک درخواست جدید بسازید، متد را
POSTانتخاب کنید و آدرسhttps://www.payam-resan.com/uapi/v4/GetAccountInfoرا وارد کنید. - در بخش Authorization، گزینه
No Authرا انتخاب کنید تا توکن یا تنظیمات احراز هویت مجموعه به این درخواست اضافه نشود. - در Body، گزینه
rawو نوعJSONرا انتخاب کنید و بدنه نمونه زیر را قرار دهید. - در Headers بررسی کنید
Content-Type: application/jsonوجود داشته باشد. با انتخاب JSON معمولاً Postman آن را تنظیم میکند؛ هدر متناقض یا تکراری اضافه نکنید. - در صورت نیاز،
Accept: application/jsonرا برای اعلام ترجیح پاسخ اضافه کنید؛ این هدر جایگزین Content-Type نیست. - کلید را در محیط امن محلی جایگزین و درخواست را ارسال کنید. سپس کد وضعیت، هدرهای پاسخ و بدنه را جداگانه بررسی کنید.
{
"ApiKey": "YOUR_API_KEY"
}برای API دیگری که واقعاً از Bearer استفاده میکند، میتوانید در Authorization گزینه Bearer Token را انتخاب و فقط مقدار توکن را وارد کنید؛ Postman هدر مربوط را میسازد. این تنظیم برای نمونه GetAccountInfo بالا لازم نیست.
تنظیم هدر در cURL
در cURL، گزینه -H هدر درخواست را اضافه میکند و -i هدرهای پاسخ را همراه بدنه نشان میدهد. نمونه زیر برای Bash و پوستههای سازگار نوشته شده است و همان درخواست Postman را اجرا میکند:
curl -i --request POST \
'https://www.payam-resan.com/uapi/v4/GetAccountInfo' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-raw '{"ApiKey":"YOUR_API_KEY"}'در این نمونه، Content-Type مطابق قرارداد API تنظیم شده و Accept ترجیح کلاینت را اعلام میکند. نیازی به واردکردن دستی Host یا Content-Length نیست. کلید واقعی را در دستورهای اشتراکی، مخزن کد یا تاریخچه قابل دسترس دیگران نگه ندارید؛ در برنامه اصلی، آن را از تنظیمات امن سمت سرور بخوانید.
طبق مستندات پیامرسان، بررسی HTTP 200 بهتنهایی کافی نیست؛ مقدار success در بدنه پاسخ را هم بخوانید. در موفقیت، داده در result قرار دارد و در شکست باید errorCode و error بررسی شوند. خطای HTTP و خطای اعلامشده در JSON را یکسان در نظر نگیرید.
نقش هدرها در CORS و امنیت چیست؟
CORS مشخص میکند مرورگر تحت چه شرایطی اجازه خواندن پاسخ یک مبدأ دیگر را به کد صفحه بدهد. سرور با هدرهایی مانند Access-Control-Allow-Origin و در پاسخ پیشدرخواست با Access-Control-Allow-Headers و Access-Control-Allow-Methods این سیاست را اعلام میکند.
اگر در مرورگر خطای CORS میبینید، اضافهکردن Access-Control-Allow-Origin به هدر درخواست راهحل نیست؛ تنظیم باید در پاسخ سرور مربوط انجام شود. موفقیت همان درخواست در Postman یا cURL نیز سالمبودن پیکربندی CORS را ثابت نمیکند، چون این ابزارها محدودیت مرورگر را اجرا نمیکنند.
در اتصال به وبسرویس پیامکی، مرورگر باید با بکاند محافظتشده برنامه شما ارتباط بگیرد و بکاند درخواست دارای ApiKey را ارسال کند. کلید محرمانه را برای رفع CORS به جاوااسکریپت مرورگر منتقل نکنید.
هدرهای امنیتی پاسخ نیز کاربرد دیگری دارند؛ برای نمونه، Strict-Transport-Security به مرورگر سیاست استفاده از HTTPS را اعلام میکند، Content-Security-Policy منابع مجاز صفحه را محدود میکند و X-Content-Type-Options: nosniff جلوی برخی رفتارهای تشخیص نوع محتوا را میگیرد. این هدرها را سرور متناسب با نیاز برنامه تنظیم میکند؛ افزودن آنها به درخواست API جای احراز هویت را نمیگیرد.

خطاهای رایج هدرهای HTTP و روش بررسی آنها
برای عیبیابی، ابتدا درخواست واقعی ارسالشده را با مستندات سرویس مقایسه کنید. فقط تنظیمات اولیه کد را نبینید؛ ابزار، مرورگر یا پروکسی ممکن است بعضی هدرها را اضافه یا تغییر داده باشد.
| نشانه | چه چیزی را بررسی کنید؟ | اقدام پیشنهادی |
|---|---|---|
| 400 Bad Request | ساختار درخواست، JSON، فیلدهای لازم و هدرهای نامعتبر | بدنه و هدرها را با نمونه مستندات مقایسه کنید؛ علت را فقط به هدر نسبت ندهید |
| 401 Unauthorized | اعتبارنامه ناقص یا نامعتبر، روش ارسال و WWW-Authenticate در صورت وجود | اعتبارنامه را در محل و قالب تعیینشده توسط سرویس ارسال کنید |
| 403 Forbidden | مجوز حساب، دسترسی به منبع یا سیاست محدودکننده سرور | مجوزها و متن پاسخ را بررسی کنید؛ تعویض توکن لزوماً مشکل را حل نمیکند |
| 415 Unsupported Media Type | Content-Type و نوع واقعی بدنه | برای بدنه JSON، نوع محتوای مورد قبول API را تنظیم کنید |
| 406 Not Acceptable | مقدار Accept و فرمتهای قابل ارائه سرور | نوع پاسخ درخواستی را با قابلیت سرویس هماهنگ کنید |
| 429 Too Many Requests | محدودیت نرخ و Retry-After در صورت وجود | نرخ درخواست را کاهش دهید و سیاست انتظار سرویس را رعایت کنید |
| خطای CORS در مرورگر | پاسخ پیشدرخواست و هدرهای CORS سمت سرور | پیکربندی مبدأها، متدها و هدرهای مجاز را بررسی کنید |
| رفتار نامنظم با وجود تنظیم ظاهراً صحیح | هدرهای تکراری، متناقض یا تنظیمات بهارثرسیده ابزار | هدرهای خروجی واقعی را ببینید و مقادیر ناخواسته را حذف کنید |
نکته: این جدول درباره وضعیتهای عمومی HTTP است و نگاشت اختصاصی خطاهای پیامرسان را مشخص نمیکند. برای این سرویس، فیلدهای خطای بدنه پاسخ را هم بررسی کنید.
همچنین در درخواست ارسال پیامک، پس از timeout بدون بررسی وضعیت، ارسال را تکرار نکنید؛ ممکن است درخواست نخست پذیرفته شده باشد.
جمعبندی
هدرهای HTTP اطلاعات لازم برای پردازش درخواست و پاسخ را منتقل میکنند؛ از نوع محتوا و احراز هویت تا کش و سیاستهای مرورگر. برای استفاده درست، تفاوت Content-Type و Accept را بدانید، اعتبارنامه را مطابق مستندات سرویس ارسال کنید و هنگام خطا، هدرها، کد وضعیت و بدنه پاسخ را جداگانه بررسی کنید.
اگر قصد اتصال سایت یا نرمافزار خود به وب سرویس پیامکی پیامرسان را دارید، نمونه درخواست همان متد را مبنا قرار دهید. در API نسخه ۴ معرفیشده در مستندات ارسالی، درخواستها با POST و بدنه JSON ارسال میشوند و ApiKey در بدنه قرار میگیرد.

