前言
这次我的项目应用了angular + 第三方c++http服务对接。没有了脱离了相熟的springboot,刚加靠近原生。也遇到了很多问题。
回绝连贯
照着第三方库启动c++服务后,在本机测试能够申请到
然而应用其余电脑,把localhost改成服务器ip就无奈申请到
通过去看github我的项目上的issue看到,大家也遇到了如此问题,最初大家的解决办法是以管理员身份运行vs并且将代码从
web::http::experimental::listener::http_listener getStatusListener(L"http://127.0.0.1:8015/getStatus");
改成
web::uri_builder uri; uri.set_scheme(U("http")); uri.set_host(U("+")); uri.set_port(U("8015")); uri.set_path(U("/getStatus")); web::http::experimental::listener::http_listener getStatusListener(uri.to_uri());
具体起因也没有具体阐明(或者我没有看懂)。问了老师后,老师倡议配置一下nginx解决。
通过这次配置nginx,了解了nginx实质上还是服务器,原来认为nginx只负责端口转发,springboot起服务作用的是tomcat。就如thinphp的apache一样。
通过nginx对申请的转发,对于c++服务来说nginx对他的申请就是localhost的地址。从而解决问题。
在后盾增加了一个post接口,用于启动捕捉数据。应用API Tester插件测试接口。
然而在启动前台单元测试进行对接的时候,申请同样的地址,产生了申请谬误。
更加奇怪的是,他间断对同一地址申请了两次,而我只操作了一次。第二次返回了200,然而服务器端也没有响应打印信息。第一次申请的CORS error报错在写上一个GET申请接口的时候也遇到过,这是因为前后台不同源,违反了同源策略,解决办法是在相应头上退出Access-Control-Allow-Origin:*
字段,容许跨域拜访。
// 响应web::http::http_response response(web::http::status_codes::OK);response.headers().add(U("Access-Control-Allow-Origin"), U("*"));response.set_body(jsonResponseFinal);request.reply(response);
然而再遇到雷同问题,这个解决办法没有胜利。
当初的问题是
1.为什么同样的谬误解决办法只实用于GET申请而不实用与POST申请?
2.并且为什么会申请了两次?
3.为什么API Tester测试没有问题?
带着这些问题问了学长。
学长看了当前发现第二次返回200的申请其实是OPTIONS申请。
什么是OPTIONS申请呢。咱们能够把OPTIONS申请当做先遣队。OPTIONS申请的主要用途有两个
一是获取服务器反对的HTTP申请办法;
二是用来查看服务器的性能。
那些可能会操作数据库的申请(除GET申请外),都会应用 OPTIONS 发动一个预检申请(preflight request),从而获知服务端是否容许该跨域申请。服务器确认容许之后,才发动理论的 HTTP 申请。
Preflighted Requests是CORS中一种通明服务器验证机制。预检申请首先须要向另外一个域名的资源发送一个 HTTP OPTIONS 申请头,其目标就是为了判断理论发送的申请是否是平安的。
上面的状况须要进行预检:
非简略申请,比方应用Content-Type 为 application/xml 或 text/xml 的 POST 申请;(什么是简略申请,什么是非简略申请,请移步阮一峰的跨域资源共享 CORS 详解)
上面借用MDN的图来更直观的看一下
所以解决也就是在options相应头退出容许申请。
web::http::experimental::listener::http_listener startCaptureListener(L"http://127.0.0.1:8015/startCapture");startCaptureListener.support(web::http::methods::POST, [&](web::http::http_request request) { this->startCapture(request);});startCaptureListener.support(web::http::methods::OPTIONS, [&](web::http::http_request request) { this->allow(request);});void YzHttp::HttpService::allow(web::http::http_request request) { web::http::http_response response(web::http::status_codes::OK); response.headers().add(U("Access-Control-Allow-Origin"), U("*")); response.headers().add(U("Access-Control-Allow-Methods"), U("POST")); response.headers().add(U("Access-Control-Allow-Headers"), U("Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")); request.reply(response);}
问题解决。
最初一个问题,为什么用API Tester测试能通过呢。可能无奈模仿真正的浏览器拜访吧。
总结
通过构建c++http服务,应用更加原生的代码。更能晓得本人有哪些http常识不分明。而springboot框架为咱们做好了所有,也让咱们没机会接触这些常识。
感激黄庭祥学长在我解决问题过程中给予的帮忙。
参考连贯
Server does not work from public IP, but localhost or other SDKs are fine
为什么会有OPTIONS申请
跨源资源共享(CORS)