http请求那点事

跳槽达人
• 阅读 2258

前言

这次项目使用了angular + 第三方c++http服务对接。没有了脱离了熟悉的springboot,刚加接近原生。也遇到了很多问题。

拒绝连接

照着第三方库启动c++服务后,在本机测试可以请求到
http请求那点事

但是使用其他电脑,把localhost改成服务器ip就无法请求到
http请求那点事
通过去看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一样。

http请求那点事
通过nginx对请求的转发,对于c++服务来说nginx对他的请求就是localhost的地址。从而解决问题。
在后台添加了一个post接口,用于启动捕获数据。使用API Tester插件测试接口。
http请求那点事
但是在启动前台单元测试进行对接的时候,请求同样的地址,发生了请求错误。
http请求那点事
更加奇怪的是,他连续对同一地址请求了两次,而我只操作了一次。第二次返回了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请求。
http请求那点事
什么是OPTIONS请求呢。我们可以把OPTIONS请求当做先遣队。OPTIONS请求的主要用途有两个
一是获取服务器支持的HTTP请求方法;
二是用来检查服务器的性能。

那些可能会操作数据库的请求(除GET请求外),都会使用 OPTIONS 发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。
下面的情况需要进行预检:
非简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求;(什么是简单请求,什么是非简单请求,请移步阮一峰的跨域资源共享 CORS 详解

下面借用MDN的图来更直观的看一下

http请求那点事
所以解决也就是在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)

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
RAC环境单实例启动数据库收到ORA
     在RAC环境中,如果你在没有启动节点的集群服务的情况下单实例启动数据库,将收到类似如下的报错:\oracle@rhel1u01\$sqlSQL\Plus:Release10.2.0.5.0ProductiononTueApr215:00:272013Copyright(
Easter79 Easter79
3年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Stella981 Stella981
3年前
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法参考文章:(1)Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.codeprj.com%2Fblo
Java服务总在半夜挂,背后的真相竟然是... | 京东云技术团队
最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
跳槽达人
跳槽达人
Lv1
我不躲不藏,等生活爱我。
文章
3
粉丝
0
获赞
0