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