Skip to content

Linux 使用 Caddy 解决 CORS 问题

Published: at 02:10 PMSuggest Changes

发现 Nginx 可以通过 proxy_set_header 来解决 CORS 问题,Caddy 也可以通过 header 来解决。

代码

一般情况下的部署是这样的,但是没有转发后端接口

:80 {
  header / {
    Access-Control-Allow-Origin *
    Access-Control-Allow-Methods GET, POST, OPTIONS
    Access-Control-Allow-Headers Origin, X-Requested-With, Content-Type, Accept
  }
}

如果需要转发后端接口,可以这样

:80 {
  header /api/* {
    Access-Control-Allow-Origin *
    Access-Control-Allow-Methods GET, POST, OPTIONS
    Access-Control-Allow-Headers Origin, X-Requested-With, Content-Type, Accept
  }
  reverse_proxy /api/* http://localhost:3000
}

比较成熟的方案

一般方案

:8088 {
    reverse_proxy /* http://xxxx:80 {
        header_up Host {http.reverse_proxy.upstream.hostport}
        header_down Access-Control-Allow-Headers *
        header_down Access-Control-Allow-Origin *
    }
}

带模块的方案

(cors) {
  @cors_preflight method OPTIONS
  @cors header Origin {args.0}

  handle @cors_preflight {
    header Access-Control-Allow-Origin "{args.0}"
    header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE"
    header Access-Control-Allow-Headers "Content-Type"
    header Access-Control-Max-Age "3600"
    respond "" 204
  }

  handle @cors {
    header Access-Control-Allow-Origin "{args.0}"
    header Access-Control-Expose-Headers "Link"
  }
}

example.com {
  import cors https://example.com
  reverse_proxy localhost:8080
}

这是网上看到的,但是存在一个问题就是写死的不够智能,比如 Access-Control-Allow-Origin 的值是 *,在请求参数中有 Cookie 的情况下就不能实现动态的跨域了。

(cors) {
  @cors_preflight method OPTIONS
  @cors header Origin {http.request.header.Origin}

  handle @cors_preflight {
    header Access-Control-Allow-Origin {http.request.header.Origin}
    header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE"
    header Access-Control-Allow-Headers "Content-Type, x-xsrf-token"
    header Access-Control-Max-Age "3600"
    header Access-Control-Allow-Credentials true
    respond "" 204
  }
}

:8088 {
    import cors http://localhost:8088
    reverse_proxy http://192.168.234.49:8080
}

还有个写法是

(cors) {
	@origin{args.0} header Origin {args.0}
	header @origin{args.0} Access-Control-Allow-Origin "{args.0}"
	header @origin{args.0} Access-Control-Allow-Headers "content-type, x-requested-with"
	header @origin{args.0} Vary Origin
}
myawesomewebsite.com {
	root * /srv/public/
	file_server
	header Access-Control-Allow-Methods "POST, GET, OPTIONS"
	@options {
		method OPTIONS
	}
	respond @options 204
	import cors https://member.myawesomewebsite.com
	import cors https://customer.myawesomewebsite.com
}

后记

如果请求参数中有 Cookie 的情况下,需要设置 Access-Control-Allow-Credentialstrue,并且 Access-Control-Allow-Origin 的值不能为 *,需要设置为请求的域名。

参考

这个是占位符的文档,可以看到有很多占位符可以使用

这个是匹配器

这个是官方 Demo

Caddy 实战

还有个 Whistle 也可以解决跨域,这儿就不多说了


Previous Post
NodeJS 证书验证失败解决方案
Next Post
JS 获取选中文本的所有 DOM 块元素