CORS (Cross-Origin Resource Sharing) は、あるドメイン上の Web アプリケーションが別のドメイン上のリソースにアクセスできるようにするメカニズムです。これは、フロントエンドとバックエンドが分離され、API を介して通信するアプリケーションを開発する場合に非常に重要です。
これは、外部ライブラリを使用せずに Node.js と Express で CORS 実装を説明する記事です:
"use strict"; /*jshint node:true */ var simpleMethods, simpleRequestHeaders, simpleResponseHeaders, toLowerCase, checkOriginMatch, origin; Object.defineProperty(exports, "simpleMethods", { get: function () { return [ "GET", "HEAD", "POST", "PUT", "DELETE" ]; } }); simpleMethods = exports.simpleMethods; Object.defineProperty(exports, "origin", { get: function () { return ["http://localhost:3000"]; } }); origin = exports.origin;
Export simpleMethods: CORS リクエストに許可される HTTP メソッド (GET、POST、PUT など) を定義します。
エクスポート起点: アクセスが許可される起点のリストを指定します。この例では、http://localhost:3000 が許可されています。
Object.defineProperty(exports, "simpleRequestHeaders", { get: function () { return ["accept", "accept-language", "content-language", "content-type", "authorization", "token"]; } }); simpleRequestHeaders = exports.simpleRequestHeaders; Object.defineProperty(exports, "simpleResponseHeaders", { get: function () { return ["cache-control", "content-language", "content-type", "expires", "last-modified", "pragma"]; } }); simpleResponseHeaders = exports.simpleResponseHeaders;
Export simpleRequestHeaders: クロスドメインリクエストでクライアントから許可されるリクエストヘッダーを定義します。
Export simpleResponseHeaders: サーバーからクライアントに許可される応答ヘッダーを定義します。
checkOriginMatch = function (originHeader, origins, callback) { if (typeof origins === "function") { origins(originHeader, function (err, allow) { callback(err, allow); }); } else if (origins.length > 0) { callback(null, origins.some(function (origin) { return origin === originHeader; })); } else { callback(null, true); } };
関数 checkOriginMatch: リクエストのオリジンが許可されたオリジンのリストと一致するかどうかを確認します。一致する場合、リクエストは許可されます。
exports.create = function (options) { options = options || {}; options.origins = options.origins || origin; options.methods = options.methods || simpleMethods;
初期化。何も指定されていない場合は、オリジンと simpleMethods からのデフォルト値が使用されます。
リクエストヘッダーとレスポンスヘッダーの設定
if (options.hasOwnProperty("requestHeaders") === true) { options.requestHeaders = toLowerCase(options.requestHeaders); } else { options.requestHeaders = simpleRequestHeaders; } if (options.hasOwnProperty("responseHeaders") === true) { options.responseHeaders = toLowerCase(options.responseHeaders); } else { options.responseHeaders = simpleResponseHeaders; }
許可されるリクエスト (requestHeaders) ヘッダーと応答 (responseHeaders) ヘッダーを設定します。指定されたリクエストまたはレスポンスのヘッダーを小文字に変換します。
追加のミドルウェア構成
options.maxAge = options.maxAge || null; options.supportsCredentials = options.supportsCredentials || false; if (options.hasOwnProperty("endPreflightRequests") === false) { options.endPreflightRequests = true; }
maxAge: CORS プリフライトの最大キャッシュ期間を指定します。 SupportsCredentials: サーバーがクロスドメイン要求で資格情報 (Cookie またはトークン) をサポートするかどうかを決定します。 endPreflightRequests: サーバーがプリフライト要求 (OPTIONS) を終了するか、次のミドルウェアに進むかを決定します。
return function (req, res, next) { if (!req.headers.hasOwnProperty("origin")) { next(); } else { checkOriginMatch(req.headers.origin, options.origins, function (err, originMatches) { if (err !== null) { next(err); } else { var endPreflight = function () { if (options.endPreflightRequests === true) { res.writeHead(204); res.end(); } else { next(); } };
関数 endPreflight: endPreflightRequests が true に設定されている場合、プリフライト (OPTIONS) リクエストを終了します。オリジン チェック: checkOriginMatch を使用して、リクエストのオリジンが許可されたオリジンと一致するかどうかを確認します。
プリフライトリクエストの処理 (オプション)
if (req.method === "OPTIONS") { if (!req.headers.hasOwnProperty("access-control-request-method")) { endPreflight(); } else { requestMethod = req.headers["access-control-request-method"]; if (req.headers.hasOwnProperty("access-control-request-headers")) { requestHeaders = toLowerCase(req.headers["access-control-request-headers"].split(/,\s*/)); } else { requestHeaders = []; } methodMatches = options.methods.indexOf(requestMethod) !== -1; if (!methodMatches) { endPreflight(); } else { headersMatch = requestHeaders.every(function (requestHeader) { return options.requestHeaders.includes(requestHeader); }); if (!headersMatch) { endPreflight(); } else { if (options.supportsCredentials) { res.setHeader("Access-Control-Allow-Origin", req.headers.origin); res.setHeader("Access-Control-Allow-Credentials", "true"); } else { res.setHeader("Access-Control-Allow-Origin", "*"); } if (options.maxAge !== null) { res.setHeader("Access-Control-Max-Age", options.maxAge); } res.setHeader("Access-Control-Allow-Methods", options.methods.join(",")); res.setHeader("Access-Control-Allow-Headers", options.requestHeaders.join(",")); endPreflight(); } } } }
リクエスト メソッドとヘッダーの一致: リクエスト メソッドとヘッダーが許可されているものと一致するかどうかを確認します。 CORS 応答ヘッダー: Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Allow-Methods などの CORS ヘッダーを設定します
Exposing Headers in the Response
} else {
if (options.supportsCredentials) {
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
res.setHeader("Access-Control-Allow-Credentials", "true");
} else {
res.setHeader("Access-Control-Allow-Origin", "*");
}
exposedHeaders = options.responseHeaders.filter(function (header) { return !simpleResponseHeaders.includes(header); }); if (exposedHeaders.length > 0) { res.setHeader("Access-Control-Expose-Headers", exposedHeaders.join(",")); } next(); } } }); } };
} else { if (options.supportsCredentials) { res.setHeader("Access-Control-Allow-Origin", req.headers.origin); res.setHeader("Access-Control-Allow-Credentials", "true"); } else { res.setHeader("Access-Control-Allow-Origin", "*"); } exposedHeaders = options.responseHeaders.filter(function (header) { return !simpleResponseHeaders.includes(header); }); if (exposedHeaders.length > 0) { res.setHeader("Access-Control-Expose-Headers", exposedHeaders.join(",")); } next(); } } }); } };
Access-Control-Expose-Headers: Sets response headers that are accessible to the client if there are custom headers not included in simpleResponseHeaders.
This is how you can implement custom CORS in Node.js without using any library. For the complete script, you can refer to this example.
以上がNodejs カスタム CORSの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。