This is the 17th day of my participation in Gwen Challenge
Koa-cors is the MIDDLEWARE used by KOA to configure CORS response headers. For details about CORS, see Cross-domain Resource Sharing CORS. It is mainly used to solve cross-domain problems.
Simple use is as follows:
const Koa = require('koa');
const cors = require('@koa/cors');
const app = new Koa();
app.use(cors());
Copy the code
Cors methods can take a single parameter, options, and return a middleware function. The parameters are as follows:
* @param {Object} [options]
* - {String|Function(ctx)} origin `Access-Control-Allow-Origin`.default is request Origin header
* - {String|Array} allowMethods `Access-Control-Allow-Methods`.default is 'GET,HEAD,PUT,POST,DELETE,PATCH'
* - {String|Array} exposeHeaders `Access-Control-Expose-Headers`
* - {String|Array} allowHeaders `Access-Control-Allow-Headers`
* - {String|Number} maxAge `Access-Control-Max-Age` in seconds
* - {Boolean} credentials `Access-Control-Allow-Credentials`
* - {Boolean} keepHeadersOnError Add set headers to `err.header` if an error is thrown
* @return {Function} cors middleware
Copy the code
The source code and analysis are as follows:
module.exports = function(options) {
// The default request method
const defaults = {
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'};// Default values are overridden if there are configuration request methodsoptions = { ... defaults, ... options, };// Configuration items that can be arrays are converted to strings
if (Array.isArray(options.exposeHeaders)) {
options.exposeHeaders = options.exposeHeaders.join(', ');
}
if (Array.isArray(options.allowMethods)) {
options.allowMethods = options.allowMethods.join(', ');
}
if (Array.isArray(options.allowHeaders)) {
options.allowHeaders = options.allowHeaders.join(', ');
}
// maxAge may be numeric and also converted to a string
if (options.maxAge) {
options.maxAge = String(options.maxAge);
}
// keepHeadersOnError defaults to true
options.keepHeadersOnError = options.keepHeadersOnError === undefined| |!!!!! options.keepHeadersOnError;// Returns the middleware function
return async function cors(ctx, next) {
// Terminate the process if origin cannot be retrieved
const requestOrigin = ctx.get('Origin');
// Always set Vary header
// https://github.com/rs/cors/issues/10
ctx.vary('Origin');
// If the request does not have Origin, no processing is done and the next middleware is executed directly
if(! requestOrigin)return await next();
// Get origin in the configuration parameter. The default is requestOrigin
let origin;
if (typeof options.origin === 'function') {
origin = options.origin(ctx);
if (origin instanceof Promise) origin = await origin;
if(! origin)return await next();
} else {
origin = options.origin || requestOrigin;
}
// Get the Credentials in the configuration parameters. The default value is false
let credentials;
if (typeof options.credentials === 'function') {
credentials = options.credentials(ctx);
if (credentials instanceof Promise) credentials = await credentials;
} else{ credentials = !! options.credentials; }const headersSet = {};
function set(key, value) {
ctx.set(key, value);
headersSet[key] = value;
}
// Non-options request, i.e. non-precheck request
// Consider configuring access-Control-allow-origin, access-Control-allow-credentials, and access-Control-expose-headers
if(ctx.method ! = ='OPTIONS') {
// Simple Cross-Origin Request, Actual Request, and Redirects
set('Access-Control-Allow-Origin', origin);
if (credentials === true) {
set('Access-Control-Allow-Credentials'.'true');
}
if (options.exposeHeaders) {
set('Access-Control-Expose-Headers', options.exposeHeaders);
}
if(! options.keepHeadersOnError) {return await next();
}
// Exception handling
try {
return await next();
} catch (err) {
const errHeadersSet = err.headers || {};
const varyWithOrigin = vary.append(errHeadersSet.vary || errHeadersSet.Vary || ' '.'Origin');
deleteerrHeadersSet.Vary; err.headers = { ... errHeadersSet, ... headersSet, ... {vary: varyWithOrigin },
};
throwerr; }}else {
// Precheck the request
// If there is no access-Control-request-method Request header, terminate the process
if(! ctx.get('Access-Control-Request-Method')) {
// this not preflight request, ignore it
return await next();
}
// Set the relevant response headers as appropriate
ctx.set('Access-Control-Allow-Origin', origin);
if (credentials === true) {
ctx.set('Access-Control-Allow-Credentials'.'true');
}
if (options.maxAge) {
ctx.set('Access-Control-Max-Age', options.maxAge);
}
if (options.allowMethods) {
ctx.set('Access-Control-Allow-Methods', options.allowMethods);
}
let allowHeaders = options.allowHeaders;
if(! allowHeaders) { allowHeaders = ctx.get('Access-Control-Request-Headers');
}
if (allowHeaders) {
ctx.set('Access-Control-Allow-Headers', allowHeaders);
}
ctx.status = 204; }}; };Copy the code
The relevant data
Cross-domain resource sharing (CORS
Koa/cors source code
The last
If the article is helpful to you, give it a thumbs up