feature: 新增 OPTIONS 请求拦截器。 (#280)
							parent
							
								
									bb47cc6a6f
								
							
						
					
					
						commit
						3048ae7ff1
					
				
							
								
								
									
										12
									
								
								README.md
								
								
								
								
							
							
						
						
									
										12
									
								
								README.md
								
								
								
								
							| 
						 | 
				
			
			@ -181,11 +181,13 @@ const intercepts = {
 | 
			
		|||
     //需要拦截url的正则表达式
 | 
			
		||||
     '/.*/.*/releases/download/': {
 | 
			
		||||
        //拦截类型
 | 
			
		||||
        // redirect: url,  临时重定向(url会变,一些下载资源可以通过此方式配置)
 | 
			
		||||
        // proxy: url,     代理(url不会变,没有跨域问题)
 | 
			
		||||
        // abort: true,    取消请求(适用于被***封锁的资源,找不到替代,直接取消请求,快速失败,节省时间)
 | 
			
		||||
        // success: true,  直接返回成功请求(某些请求不想发出去,可以伪装成功返回)
 | 
			
		||||
        // cacheDays: 1,   GET请求的缓存时间,单位天(常用于一些静态资源)
 | 
			
		||||
        // redirect: url,          // 临时重定向(url会变,一些下载资源可以通过此方式配置)
 | 
			
		||||
        // proxy: url,             // 代理(url不会变,没有跨域问题)
 | 
			
		||||
        // abort: true,            // 取消请求(适用于被***封锁的资源,找不到替代,直接取消请求,快速失败,节省时间)
 | 
			
		||||
        // success: true,          // 直接返回成功请求(某些请求不想发出去,可以伪装成功返回)
 | 
			
		||||
        // cacheDays: 1,           // GET请求的使用缓存,单位:天(常用于一些静态资源)
 | 
			
		||||
        // options: true,          // OPTIONS请求直接返回成功请求(该功能存在一定风险,请谨慎使用)
 | 
			
		||||
        // optionsMaxAge: 2592000, // OPTIONS请求缓存时间,默认:2592000(一个月)
 | 
			
		||||
        redirect: 'download.fastgit.org'
 | 
			
		||||
      },
 | 
			
		||||
      '.*':{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
// eslint-disable-next-line no-unused-vars
 | 
			
		||||
const start = require('./start/index.js')
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
const https = require('https')
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
const defaultAllowHeaders = '*'
 | 
			
		||||
const defaultAllowMethods = 'GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH' // CONNECT、TRACE被认为是不安全的请求,通常不建议允许跨域
 | 
			
		||||
 | 
			
		||||
function readConfig (config, defaultConfig) {
 | 
			
		||||
  if (config) {
 | 
			
		||||
    if (Object.isArray(config)) {
 | 
			
		||||
      config = config.join(',')
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    config = defaultConfig
 | 
			
		||||
  }
 | 
			
		||||
  return config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  requestIntercept (context, interceptOpt, req, res, ssl, next) {
 | 
			
		||||
    const { rOptions, log } = context
 | 
			
		||||
 | 
			
		||||
    // 不是 OPTIONS 请求,或请求头中不含 origin 时,跳过当前拦截器
 | 
			
		||||
    if (rOptions.method !== 'OPTIONS' || rOptions.headers.origin == null) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 从请求头中获取跨域相关信息;如果不存在,则从配置中获取的值;如果还不存在,则使用默认值
 | 
			
		||||
    const allowHeaders = rOptions.headers['access-control-request-headers'] || readConfig(interceptOpt.optionsAllowHeaders, defaultAllowHeaders)
 | 
			
		||||
    const allowMethods = rOptions.headers['access-control-request-method'] || readConfig(interceptOpt.optionsAllowMethods, defaultAllowMethods)
 | 
			
		||||
 | 
			
		||||
    const headers = {
 | 
			
		||||
      // 允许跨域
 | 
			
		||||
      'Dev-Sidecar-Interceptor': 'options',
 | 
			
		||||
      'Access-Control-Allow-Origin': rOptions.headers.origin,
 | 
			
		||||
      'Access-Control-Allow-Headers': allowHeaders,
 | 
			
		||||
      'Access-Control-Allow-Methods': allowMethods,
 | 
			
		||||
      'Access-Control-Max-Age': interceptOpt.optionsMaxAge > 0 ? interceptOpt.optionsMaxAge : 2592000, // 默认有效一个月
 | 
			
		||||
      Date: new Date().toUTCString()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 判断是否允许
 | 
			
		||||
    if (interceptOpt.optionsCredentials !== false && interceptOpt.optionsCredentials !== 'false') {
 | 
			
		||||
      headers['Access-Control-Allow-Credentials'] = 'true'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    res.writeHead(200, headers)
 | 
			
		||||
    res.end()
 | 
			
		||||
 | 
			
		||||
    log.info('options intercept:', (rOptions.original || rOptions).url)
 | 
			
		||||
    return true // true代表请求结束
 | 
			
		||||
  },
 | 
			
		||||
  is (interceptOpt) {
 | 
			
		||||
    return !!interceptOpt.options
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
// request interceptor impls
 | 
			
		||||
const OPTIONS = require('./impl/req/OPTIONS.js')
 | 
			
		||||
 | 
			
		||||
const success = require('./impl/req/success')
 | 
			
		||||
const redirect = require('./impl/req/redirect')
 | 
			
		||||
const abort = require('./impl/req/abort')
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +16,7 @@ const script = require('./impl/res/script')
 | 
			
		|||
 | 
			
		||||
module.exports = [
 | 
			
		||||
  // request interceptor impls
 | 
			
		||||
  OPTIONS,
 | 
			
		||||
  success, redirect, abort,
 | 
			
		||||
  cacheReq,
 | 
			
		||||
  proxy, sni,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
const os = require('os')
 | 
			
		||||
module.exports = {
 | 
			
		||||
  isWindows7 () {
 | 
			
		||||
    const version = os.release()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue