CORS
جزء من قسم واجهات REST API في رحلة Node.js على Coddy. الدرس 13 من 18.
تستدعي صفحة على https://board.example.com واجهة API البرمجية الخاصة بك باستخدام fetch، ويحظر المتصفح الاستجابة. تتيح المتصفحات للصفحة قراءة الاستجابات من المصدر الخاص بها فقط، أي المخطط والمضيف والمنفذ الذي جاءت منه، ما لم يسمح الخادم لمصادر أخرى بذلك باستخدام ترويسات CORS.
OPTIONS /api/products/7
Origin: https://shop.example.com
Access-Control-Request-Method: DELETE
204 No Content
Access-Control-Allow-Origin: https://shop.example.com
Access-Control-Allow-Methods: GET, DELETE
Access-Control-Allow-Headers: Content-Typeقبل طلب DELETE أو PATCH أو إرسال جسم JSON، يرسل المتصفح طلب التمهيد المسبق هذا، ولا يتابع إلا إذا سمحت الاستجابة بذلك. تحتاج كل الاستجابات الأخرى أيضًا إلى Access-Control-Allow-Origin. يسمح * بأي مصدر، لكن المتصفحات ترفضه عندما ترسل الصفحة ملفات تعريف الارتباط (Access-Control-Allow-Credentials: true)، لذا حدّد المصدر بالاسم. المتصفحات وحدها هي التي تفرض قيود CORS: إذ يتجاهلها كلٌّ من curl وشريط الطلبات.
التحدي
سهل- تضبط برمجية وسيطة تسبق المسارات
Access-Control-Allow-Origin: https://board.example.comوAccess-Control-Allow-Credentials: trueفي كل استجابة. - تعيد
OPTIONSاستجابةً برمز 204، وتُدرجAccess-Control-Allow-Methodsالطرق GET وPOST وPUT وPATCH وDELETE، كما تُدرجAccess-Control-Allow-Headers: Content-Type.
مثّل دور المتصفح: أرسل OPTIONS /api/tasks/2 مع الترويسة Origin: https://board.example.com، ثم أرسل GET /api/tasks، واقرأ ترويسات كل استجابة.
جرّب بنفسك
import express from 'express';
import { sendError } from './errors.js';
import taskRoutes from './routes/tasks.js';
const app = express();
app.use(express.json());
app.use('/api/tasks', taskRoutes);
// تنتهي هنا الأخطاء الواردة من المسارات. إذا لم يكن محتوى الطلب JSON صالحًا، فهذا
// خطأ العميل (400)؛ وأي خطأ آخر فهو من جانبنا (500).
app.use((err, req, res, next) => {
if (err.type === 'entity.parse.failed') {
return sendError(res, 400, 'invalid_json', 'The body is not valid JSON');
}
console.error(err);
sendError(res, 500, 'server_error', 'Something went wrong');
});
app.listen(3000, () => {
console.log('Task tracker API on port 3000');
});
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.