在做静态博客评论系统时使用的是与主站www.qttc.net
不同的域cume.qttc.net
,这会造成一个跨域问题。在浏览器下使用XML Http Request
或者fetch
发出一个HTTP请求,假如这个HTTP的协议、主机名或者端口任意一个与当前网页地址有不一致时,为了安全浏览器会限制响应结果,通常这类问题就是所谓的跨域问题。
解决跨域问题的方式有很多,比如jsonp
,iframe
等等。但在这里,我使用HTTP协议里约定的字段来解决这个问题,这也是最干净完美的解决方案。为了处理有跨域请求的特殊场景,HTTP协议里有一个特殊的响应头字段Access-Control-Allow-Origin
,意思允许访问的Origin
,值可以是通配符*
,允许所有,或者写上一个具体的Origin
值。
在actix-web
里, 我们需要配合actix_cors
来处理关于跨域请求的配置,以下是一个例子
Cargo.toml
[package]
name = "actix-web-cors"
version = "1.0.0"
authors = ["Nicholas <lizhongit@gmail.com>"]
edition = "2018"
[dependencies]
actix-rt = "1.0.0"
actix-web = "2.0.0"
actix-cors = "0.2.0"
futures = "0.3"
main.rs
use actix_cors::Cors;
use actix_web::{web, App, HttpServer, Responder};
async fn index() -> impl Responder {
"Hi, This is CORS request result\r\n"
}
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(move || {
App::new()
.wrap(
Cors::new()
.allowed_origin("https://www.qttc.net")
.allowed_methods(vec!["GET"])
.max_age(3600)
.finish(),
)
.route("/resource", web::get().to(index))
})
.bind("127.0.0.1:8000")?
.run()
.await
}
测试一下
$ curl -iv -H 'Origin: https://www.qttc.net' 127.0.0.1:8000/resource
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /resource HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.64.1
> Accept: */*
> Origin: https://www.qttc.net
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< content-length: 33
content-length: 33
< vary: Origin
vary: Origin
< content-type: text/plain; charset=utf-8
content-type: text/plain; charset=utf-8
< access-control-allow-origin: https://www.qttc.net
access-control-allow-origin: https://www.qttc.net
< date: Wed, 03 Jun 2020 09:02:47 GMT
date: Wed, 03 Jun 2020 09:02:47 GMT
<
Hi, This is CORS request result
* Connection #0 to host 127.0.0.1 left intact
* Closing connection 0
如果我们把http
换成https
看看结果
$ curl -iv -H 'Origin: https://www.qttc.net' 127.0.0.1:8000/resource
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /resource HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.64.1
> Accept: */*
> Origin: https://www.qttc.net
>
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< content-length: 42
content-length: 42
< date: Wed, 03 Jun 2020 09:34:50 GMT
date: Wed, 03 Jun 2020 09:34:50 GMT
<
* Connection #0 to host 127.0.0.1 left intact
Origin is not allowed to make this request* Closing connection 0
400出错了,提示
Origin is not allowed to make this request
不允许的Origin请求,https://www.qttc.net
和https://www.qttc.net
被视为两个不同的Origin
,所以如果要支持多个Origin
就需要调用多次allowed_origin
这个API增加
allowed_origin("https://www.qttc.net")
allowed_origin("https://www.qttc.net")
如果你需要允许所有的Origin
,也就是不做限制的话,那么使用*
号做通配符
allowed_origin("*")
通常来说不建议这么干