منابع آموزشی و پژوهشی، برای دانشگاه و مدرسه
پشتیبانیانتشار محتوا
مسیر یادگیری

جاوااسکریپت ۲؛ دورهٔ متوسط و پروژه‌های کاربردی

دورهٔ دوم و رایگان جاوااسکریپت، تألیف تحریریه درس‌آوند؛ ادامهٔ دورهٔ «جاوااسکریپت از صفر تا پروژه». ۲۴ درس سطح متوسط با مثال عملی، تمرین و پاسخ و سه پروژهٔ مدیریت هزینه، فروشگاه و API محلی تیکت. پیش‌نیاز: تسلط بر مبانی دورهٔ اول و HTML مقدماتی. زمان هر درس برآورد مطالعه و تمرین است؛ این نسخه ویدیو ندارد.

۲۴ درس۱٬۱۰۰ دقیقه۰ درس کامل‌شده
پرسش دربارهٔ این دوره
API تیکت، آزمون و کیفیت · درس ۱۹

۱۹. پروژهٔ سوم؛ قرارداد API تیکت و مالکیت داده

دورهٔ رایگانثبت‌نام و پیشرفت یادگیری در حساب شما نگهداری می‌شود.ورود / ساخت حساب

در دو پروژهٔ قبلی، بیشتر تصمیم‌ها داخل مرورگر بودند. اکنون داده بین چند هویت آزمایشی مشترک است و مرورگر نمی‌تواند مرجع مالکیت باشد. هدف درس، فهم مسیر «درخواست، بررسی، تغییر و پاسخ» در API محلی Node.js است. این پروژه یک مرکز تیکت آموزشی با فایل JSON است؛ انتخاب آلیس، باب یا کارشناس آزمایشی، ورود واقعی و امن برای استفادهٔ عمومی نیست. سرور فقط روی 127.0.0.1 اجرا می‌شود و نباید همین نسخه را به اینترنت باز کنید.

قرارداد را پیش از رابط بخوانید

در ریشهٔ بسته npm start را اجرا و صفحهٔ /support/ را در نشانی چاپ‌شدهٔ ترمینال باز کنید. مسیر GET /api/tickets فهرست تیکت‌های مجاز را برمی‌گرداند. POST روی همان مسیر برای ایجاد تیکت است و فقط title و message و category را می‌پذیرد. عنوان ۶ تا ۱۲۰ و پیام نخست ۲۰ تا ۳۰۰۰ نویسه پس از trim لازم دارد. دسته باید یکی از مقادیر مدل باشد؛ برای تمرین از course استفاده می‌کنیم.

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

javascript
const sessionResponse = await fetch('/api/demo-session', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ profile: 'alice' })
});
console.log(sessionResponse.status); // 200

const createdResponse = await fetch('/api/tickets', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'پرسش دربارهٔ تمرین سبد خرید',
    message: 'با افزودن سومین کالا خطای موجودی دریافت می‌کنم؛ انتظار چیست؟',
    category: 'course'
  })
});
const ticket = await createdResponse.json();
console.log(createdResponse.status, ticket.owner, ticket.version);
// 201 alice 1

در مرورگر، Origin درخواست هم‌مبدأ به شکل معمول ارسال می‌شود. در آزمون Node باید آن را صریح بسازیم. نمونه برای اجرای کنسولی است و موفقیت را صرفاً از وجود JSON نتیجه نمی‌گیرد؛ کد وضعیت نیز مهم است. در برنامهٔ اصلی، تابع api خطای پاسخ ناموفق را به Error تبدیل می‌کند تا فرم در مسیر موفقیت پاک نشود.

مالک از نشست می‌آید

کلاینت اجازه ندارد owner را انتخاب کند. اگر به بدنهٔ ساخت تیکت owner:'bob' اضافه کنید، سرور به علت فیلد اضافی 400 می‌دهد. سرور user را از نشست فعلی پیدا و owner را از user.id می‌سازد. برای خواندن نیز canRead هر رکورد را بررسی می‌کند: مالک یا کارشناس آزمایشی مجاز است. ناشناخته‌بودن UUID به‌تنهایی کنترل دسترسی نیست.

نمونهٔ دوم مستقل است و منطق خالص همان مدل را در Node بررسی می‌کند. آن را در ریشهٔ بسته با نام ownership-demo.mjs ذخیره و node ownership-demo.mjs اجرا کنید.

javascript
import { canRead, nextStatus } from './projects/support/model.mjs';
const ticket = { owner: 'alice', status: 'open' };
const alice = { id: 'alice', role: 'student' };
const bob = { id: 'bob', role: 'student' };
const staff = { id: 'staff', role: 'staff' };
console.log(canRead(ticket, alice), canRead(ticket, bob)); // true false
console.log(nextStatus(ticket, staff, 'reply')); // waiting
console.log(nextStatus(ticket, alice, 'reply')); // open

این مدل می‌گوید پاسخ کارشناس وضعیت را waiting، یعنی انتظار پاسخ دانشجو، می‌کند. پاسخ مالک وضعیت را open می‌کند. تیکت بسته تا بازگشایی پاسخ تازه نمی‌گیرد. این نام‌گذاری قرارداد همین پروژه است؛ آن را با معنای وضعیت در یک سامانهٔ دیگر اشتباه نگیرید. نمایش فارسی وضعیت در فایل رابط جداست تا منطق مدل به متن صفحه وابسته نباشد.

فایل داده و محدودهٔ تضمین

server.mjs داده را ابتدا در فایل موقت می‌نویسد و سپس جایگزین می‌کند. این روش برای آزمایشگاه تک‌فرایندی ما روشن و قابل بررسی است؛ پایگاه دادهٔ تراکنشی چندسروری نیست. نشست‌ها در حافظه‌اند و با راه‌اندازی دوباره از بین می‌روند؛ تیکت‌ها در فایل داده می‌مانند. بنابراین باقی‌ماندن تیکت بعد از restart و خارج‌شدن از نشست دو رفتار متناقض نیستند.

فهرست، متن پیام‌های همهٔ تیکت‌ها را نمی‌فرستد؛ برای مشاهدهٔ رشته باید مسیر GET /api/tickets/{id} را بخوانید. این تفکیک به خوانایی قرارداد و کاهش دادهٔ غیرضروری کمک می‌کند. خطای 404 برای تیکت ناموجود و تیکت غیرمجاز یکسان است. از آن نتیجه نگیرید که رکورد حتماً وجود ندارد؛ فقط برای این درخواست قابل دسترس نیست.

تمرین، پاسخ راهنما و معیار تحویل

یک تیکت با آلیس بسازید، شناسه‌اش را یادداشت کنید و با رابط به باب تغییر هویت بدهید. باب نباید آن را در فهرست ببیند. درخواست مستقیم خواندن همان شناسه هم باید 404 بگیرد. سپس به کارشناس آزمایشی بروید و پاسخ بدهید؛ وضعیت باید waiting شود. پاسخ راهنما این است که مخفی‌کردن دکمه به‌تنهایی کافی نیست؛ موفقیت تمرین به رد درخواست مستقیم روی سرور بستگی دارد.

گزارش تحویل باید بدنهٔ مجاز ساخت، سه هویت آزمایشی، مسیر خواندن و رفتار مالکیت را توضیح دهد. اگر owner را از localStorage می‌خوانید یا به دادهٔ بدنه اعتماد می‌کنید، مدل را اصلاح کنید. هدف یادگیری مرز اعتماد است و ادعای ساخت یک سامانهٔ احراز هویت تولیدی در این درس نداریم.

منابع رسمی برای مطالعهٔ بیشتر

https://nodejs.org/docs/latest-v24.x/api/http.html
https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html

تألیف و مثال‌های اختصاصی: تحریریه درس‌آوند.

یکجا انتخاب کن، راحت‌تر دریافت کن

انتخاب‌های من ۰ منبع

مجموعهٔ مطالعه‌ات را بساز.

کنار مقاله‌ها «انتخاب» را بزنید تا چند فایل را با هم دریافت کنید.

انتخاب مقاله‌های رایگان