前言
最近有同事在开发时,遇到一些跨域问题,笔者简单整理了下问题,供需要的小伙伴参考
问题一
web前端的get请求无法获取数据,浏览器提示Reason: CORS header 'Access-Control-Allow-Origin' missing
解决方法:
在响应返回时,添加允许跨域的头,以下笔者的程序片段
m_httpServer->route("/captchaImage", QHttpServerRequest::Method::Get,
[this](const QHttpServerRequest &) {
QHttpServerResponse response(m_userController->getCaptchaImage());
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
return response;
});
问题二
web前端的post请求无法获取数据,浏览器提示Reason: CORS header 'Access-Control-Allow-Origin' missing
笔者尝试使用客户端检查返回值,没有异常。但在经过网络抓包分析发现,存在再次请求,第一次请求方法是option,第二条请求才是post请求
![](https://i-blog.csdnimg.cn/blog_migrate/7944f8b7a62be25a36d17bb7d4ed5247.png)
解决方法
在options请求时,只要返回的头里允许跨域就可以。据此笔者修改的代码片段如下
m_httpServer->route("/login", QHttpServerRequest::Method::Post | QHttpServerRequest::Method::Options ,
[this](const QHttpServerRequest &request) {
if(request.method() != QHttpServerRequest::Method::Post)
return QHttpServerResponse("");
QHttpServerResponse response(m_userController->loginResponse(request.body()));
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
return response;
});
改进
因为每次请求,仅需要在返回的响应中添加头,因此可以使用后处理。即每次请求正常处理,仅在最后再添加一个后处理。笔者修改的代码片段如下
m_httpServer->afterRequest([](QHttpServerResponse &&response) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
return std::move(response);
});
m_httpServer->route("/captchaImage", QHttpServerRequest::Method::Get,
[this](const QHttpServerRequest &) {
QHttpServerResponse response(m_userController->getCaptchaImage());
return response;
});
m_httpServer->route("/login", QHttpServerRequest::Method::Post | QHttpServerRequest::Method::Options ,
[this](const QHttpServerRequest &request) {
if(request.method() != QHttpServerRequest::Method::Post)
return QHttpServerResponse("");
QHttpServerResponse response(m_userController->loginResponse(request.body()));
return response;
});
注:
笔者建议,若非必要,还是不要允许跨域的
笔者使用的源码下载
后记
笔者并非web开发专业人员,当前进行web测试时才注意到,有不少限制。不过相信随着规范不断完善,各个问题会逐步解决的。