bugfix: OPTIONS 拦截器,在正式请求中缺少响应头 `'Access-Control-Allow-Credentials': 'true'` 的问题修复。
parent
13741d3b15
commit
51366cf2c8
|
@ -1,24 +1,28 @@
|
||||||
const responseReplaceApi = require('./responseReplace')
|
const responseReplaceApi = require('./responseReplace')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'OPTIONSHeaders',
|
name: 'AfterOPTIONSHeaders',
|
||||||
desc: '开启了options.js功能时,正常请求时,会需要增加响应头 `Access-Control-Allow-Origin: xxx`',
|
desc: '开启了options.js功能时,正常请求时,会需要增加响应头 `Access-Control-Allow-Origin: xxx`',
|
||||||
priority: 201,
|
priority: 201,
|
||||||
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
||||||
const { rOptions, log } = context
|
const { rOptions, log } = context
|
||||||
|
|
||||||
if (rOptions.method === 'OPTIONS') {
|
if (rOptions.method === 'OPTIONS' || rOptions.headers.origin == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
|
'Access-Control-Allow-Credentials': 'true',
|
||||||
'Access-Control-Allow-Origin': rOptions.headers.origin,
|
'Access-Control-Allow-Origin': rOptions.headers.origin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.setHeader('DS-AfterOPTIONSHeaders-Interceptor', '1')
|
||||||
|
|
||||||
// 替换响应头
|
// 替换响应头
|
||||||
if (responseReplaceApi.replaceResponseHeaders({ ...headers }, res, proxyRes)) {
|
if (responseReplaceApi.replaceResponseHeaders({ ...headers }, res, proxyRes)) {
|
||||||
res.setHeader('DS-AfterOPTIONSHeaders-Interceptor', rOptions.headers.origin)
|
|
||||||
log.info('AfterOPTIONSHeaders intercept:', JSON.stringify(headers))
|
log.info('AfterOPTIONSHeaders intercept:', JSON.stringify(headers))
|
||||||
|
} else {
|
||||||
|
res.setHeader('DS-AfterOPTIONSHeaders-Interceptor', '0')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
is (interceptOpt) {
|
is (interceptOpt) {
|
||||||
|
|
|
@ -5,62 +5,62 @@ const REMOVE = '[remove]'
|
||||||
|
|
||||||
// 替换响应头
|
// 替换响应头
|
||||||
function replaceResponseHeaders (newHeaders, res, proxyRes) {
|
function replaceResponseHeaders (newHeaders, res, proxyRes) {
|
||||||
if (newHeaders && !lodash.isEmpty(newHeaders)) {
|
if (!newHeaders || lodash.isEmpty(newHeaders)) {
|
||||||
// 响应头Key统一转小写
|
return null
|
||||||
for (const headerKey in newHeaders) {
|
|
||||||
if (headerKey === headerKey.toLowerCase()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
const value = newHeaders[headerKey]
|
|
||||||
delete newHeaders[headerKey]
|
|
||||||
newHeaders[headerKey.toLowerCase()] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// 原先响应头
|
|
||||||
const preHeaders = {}
|
|
||||||
|
|
||||||
// 替换响应头
|
|
||||||
const needDeleteKeys = []
|
|
||||||
for (let i = 0; i < proxyRes.rawHeaders.length; i += 2) {
|
|
||||||
const headerKey = proxyRes.rawHeaders[i].toLowerCase()
|
|
||||||
|
|
||||||
const newHeaderValue = newHeaders[headerKey]
|
|
||||||
if (newHeaderValue) {
|
|
||||||
if (newHeaderValue !== proxyRes.rawHeaders[i + 1]) {
|
|
||||||
preHeaders[headerKey] = proxyRes.rawHeaders[i + 1] // 先保存原先响应头
|
|
||||||
if (newHeaderValue === REMOVE) { // 由于拦截配置中不允许配置null,会被删,所以配置一个 "[remove]",当作删除响应头的意思
|
|
||||||
proxyRes.rawHeaders[i + 1] = ''
|
|
||||||
} else {
|
|
||||||
proxyRes.rawHeaders[i + 1] = newHeaderValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
needDeleteKeys.push(headerKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 处理删除响应头
|
|
||||||
for (const headerKey of needDeleteKeys) {
|
|
||||||
delete newHeaders[headerKey]
|
|
||||||
}
|
|
||||||
// 新增响应头
|
|
||||||
for (const headerKey in newHeaders) {
|
|
||||||
const headerValue = newHeaders[headerKey]
|
|
||||||
if (headerValue == null || headerValue === REMOVE) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
res.setHeader(headerKey, newHeaders[headerKey])
|
|
||||||
preHeaders[headerKey] = null // 标记原先响应头为null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lodash.isEmpty(preHeaders)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
// 返回原先响应头
|
|
||||||
return preHeaders
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
// 响应头Key统一转小写
|
||||||
|
for (const headerKey in newHeaders) {
|
||||||
|
if (headerKey === headerKey.toLowerCase()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = newHeaders[headerKey]
|
||||||
|
delete newHeaders[headerKey]
|
||||||
|
newHeaders[headerKey.toLowerCase()] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 原先响应头
|
||||||
|
const preHeaders = {}
|
||||||
|
|
||||||
|
// 替换响应头
|
||||||
|
const needDeleteKeys = []
|
||||||
|
for (let i = 0; i < proxyRes.rawHeaders.length; i += 2) {
|
||||||
|
const headerKey = proxyRes.rawHeaders[i].toLowerCase()
|
||||||
|
|
||||||
|
const newHeaderValue = newHeaders[headerKey]
|
||||||
|
if (newHeaderValue) {
|
||||||
|
if (newHeaderValue !== proxyRes.rawHeaders[i + 1]) {
|
||||||
|
preHeaders[headerKey] = proxyRes.rawHeaders[i + 1] // 先保存原先响应头
|
||||||
|
if (newHeaderValue === REMOVE) { // 由于拦截配置中不允许配置null,会被删,所以配置一个 "[remove]",当作删除响应头的意思
|
||||||
|
proxyRes.rawHeaders[i + 1] = ''
|
||||||
|
} else {
|
||||||
|
proxyRes.rawHeaders[i + 1] = newHeaderValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
needDeleteKeys.push(headerKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理删除响应头
|
||||||
|
for (const headerKey of needDeleteKeys) {
|
||||||
|
delete newHeaders[headerKey]
|
||||||
|
}
|
||||||
|
// 新增响应头
|
||||||
|
for (const headerKey in newHeaders) {
|
||||||
|
const headerValue = newHeaders[headerKey]
|
||||||
|
if (headerValue == null || headerValue === REMOVE) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader(headerKey, newHeaders[headerKey])
|
||||||
|
preHeaders[headerKey] = null // 标记原先响应头为null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lodash.isEmpty(preHeaders)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
// 返回原先响应头
|
||||||
|
return preHeaders
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -15,7 +15,7 @@ const unVerifySsl = require('./impl/req/unVerifySsl')
|
||||||
const baiduOcr = require('./impl/req/baiduOcr')
|
const baiduOcr = require('./impl/req/baiduOcr')
|
||||||
|
|
||||||
// response interceptor impls
|
// response interceptor impls
|
||||||
const OPTIONSHeaders = require('./impl/res/AfterOPTIONSHeaders')
|
const AfterOPTIONSHeaders = require('./impl/res/AfterOPTIONSHeaders')
|
||||||
const cacheRes = require('./impl/res/cacheRes')
|
const cacheRes = require('./impl/res/cacheRes')
|
||||||
const responseReplace = require('./impl/res/responseReplace')
|
const responseReplace = require('./impl/res/responseReplace')
|
||||||
|
|
||||||
|
@ -30,6 +30,6 @@ module.exports = [
|
||||||
baiduOcr,
|
baiduOcr,
|
||||||
|
|
||||||
// response interceptor impls
|
// response interceptor impls
|
||||||
OPTIONSHeaders, cacheRes, responseReplace,
|
AfterOPTIONSHeaders, cacheRes, responseReplace,
|
||||||
script,
|
script,
|
||||||
]
|
]
|
||||||
|
|
|
@ -13,8 +13,8 @@ const proxyRes = {
|
||||||
'Content-Length', '2',
|
'Content-Length', '2',
|
||||||
'ETag', 'W/"2"',
|
'ETag', 'W/"2"',
|
||||||
'Date', 'Thu, 01 Jan 1970 00:00:00 GMT',
|
'Date', 'Thu, 01 Jan 1970 00:00:00 GMT',
|
||||||
'Connection', 'keep-alive'
|
'Connection', 'keep-alive',
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
const newHeaders = {
|
const newHeaders = {
|
||||||
|
|
Loading…
Reference in New Issue