http-enc-res-hdr.lua 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. -- 功能:编码 HTTP 返回头
  2. -- 阶段:header_filter_by_lua
  3. -- 备注:
  4. -- aceh = HTTP 返回头的 access-control-expose-headers 字段
  5. -- 无论浏览器是否支持,aceh 始终包含 *
  6. local expose = '*'
  7. -- 该值为 true 表示浏览器不支持 aceh: *,需返回详细的头部列表
  8. local detail = (ngx.ctx._aceh == 1)
  9. -- 由于接口路径固定,为避免被缓存,以请求头的 --url 值区分缓存
  10. local vary = '--url'
  11. local h, err = ngx.resp.get_headers()
  12. for k, v in pairs(h) do
  13. if
  14. -- 这些头有特殊意义,需要转义 --
  15. k == 'access-control-allow-origin' or
  16. k == 'access-control-expose-headers' or
  17. k == 'location' or
  18. k == 'set-cookie'
  19. then
  20. if type(v) == 'table' then
  21. -- 如果存在重名字段(例如 Set-Cookie)
  22. -- 则转义成:0-Set-Cookie, 1-Set-Cookie, ...
  23. for i = 1, #v do
  24. local x = i .. '-' .. k
  25. ngx.header[x] = v[i]
  26. if detail then
  27. expose = expose .. ',' .. x
  28. end
  29. end
  30. else
  31. -- 默认转义成:--Set-Cookie
  32. local x = '--' .. k
  33. ngx.header[x] = v
  34. if detail then
  35. expose = expose .. ',' .. x
  36. end
  37. end
  38. -- 删除原始字段
  39. ngx.header[k] = nil
  40. elseif k == 'vary' then
  41. if type(v) == 'table' then
  42. vary = vary .. ',' .. table.concat(v, ',')
  43. else
  44. vary = vary .. ',' .. v
  45. end
  46. elseif detail and
  47. -- 非简单头无法被 fetch 读取,需添加到 aceh 列表 --
  48. -- https://developer.mozilla.org/en-US/docs/Glossary/Simple_response_header
  49. k ~= 'cache-control' and
  50. k ~= 'content-language' and
  51. k ~= 'content-type' and
  52. k ~= 'expires' and
  53. k ~= 'last-modified' and
  54. k ~= 'pragma'
  55. then
  56. expose = expose .. ',' .. k
  57. end
  58. end
  59. if detail then
  60. expose = expose .. ',--s'
  61. -- 该字段不在 aceh 中,如果浏览器能读取到,说明支持 aceh: *
  62. ngx.header['--t'] = '1'
  63. end
  64. ngx.header['access-control-expose-headers'] = expose
  65. ngx.header['access-control-allow-origin'] = '*'
  66. ngx.header['vary'] = vary
  67. ngx.header['--s'] = ngx.status
  68. ngx.status = 200