HTTP之put/post请求头中的Expect:100-continue

本文探讨了curl在上传大文件时的预请求问题,即在实际数据传输前发送Expect: 100-continue请求,增加了请求时间并可能造成业务逻辑错误。文章提供了设置Expect请求头为空的解决方案,有效提升系统性能。

在使用curl封装的HTTPClient时,在上传文件的put方法中,通过抓包抓包数据分析,发现在每次真正传输数据之前都必须要收到Server端的响应:HTTP/1.1 100 Continue,这无疑增加了请求的时间;

使用 curl 发送 POST 请求时,如果 POST 数据大于 1024字节,curl 默认行为 如下:

  1. 先追加一个Expect: 100-continue请求头信息,发送这个不包含 POST 数据的请求;
  2. 如果服务器返回的响应头信息中包含Expect: 100-continue,则表示 Server 愿意接受数据,这时才 POST 真正数据给 Server;

因此如果client预期等待“100-continue”的应答,那么它发送的请求必须包含一个“Expect: 100-continue” ;

可见此时,curl 发送了一次不必要的 HTTP 请求,从系统性能上来说这是不允许的。另外,并不是所有的 Server 都会正确响应100-continue,反而会返回417 Expectation Failed,curl 端不会发起数据 POST 请求,则会造成业务逻辑错误,我们应该避免这种情况的发生。

解决办法:

只需 设置 Expect 请求头为空 即可。

在封装接口时,我们可以做如下的则设置:

        struct curl_slist *headers = NULL;
	headers = curl_slist_append(headers, "Expect:");  //注意此处的操作
	headers = curl_slist_append(headers, "Connection:keep-alive");
	/* 1: set http server url */
	curl_easy_setopt(curl, CURLOPT_URL, serv_url);

	// 3.4:put & upload
	curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
	curl_easy_setopt(curl, CURLOPT_PUT, 1);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
	curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_read_func);
	curl_easy_setopt(curl, CURLOPT_READDATA, fp);
	curl_easy_setopt(curl, CURLOPT_INFILESIZE, local_file_length);

	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
	/* abort if slower than 1 bytes/sec during 6 seconds */
	curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
	curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 6);
        ......

再次抓包,发现使用 curl 发送超过 1024字节 的 PUT/POST 数据时,也并未出现 100-continue 的 HTTP 请求。

现在是发了options请求之后不发mkcol请求了 是不发了 D:\UserData\Desktop>curl -X OPTIONS “http://192.168.0.1:8085” -H “Origin: http://192.168.0.1:80” -H “Access-Control-Request-Method: MKCOL” -H “Access-Control-Request-Headers: Depth” -I HTTP/1.1 200 OK DAV: 1,2,3 MS-Author-Via: DAV Allow: PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK, OPTIONS, GET, HEAD, POST Access-Control-Allow-Origin: http://192.168.0.1:80 Access-Control-Allow-Methods: MKCOL, PUT, DELETE, OPTIONS, GET, POST Access-Control-Allow-Headers: Content-Type, Authorization, Depth Access-Control-Max-Age: 86400 Content-Length: 0 Date: Fri, 08 Aug 2025 00:43:15 GMT Server: lighttpd/1.4.71 但是我这么运行就可以正常了 D:\UserData\Desktop>curl -X MKCOL “http://192.168.0.1:8085/E/resource1” -H “Origin: http://192.168.0.1:80” -I HTTP/1.1 200 OK Access-Control-Allow-Origin: http://192.168.0.1:80 Access-Control-Allow-Methods: MKCOL, PUT, DELETE, OPTIONS, GET, POST Access-Control-Allow-Headers: Content-Type, Authorization, Depth Access-Control-Max-Age: 86400 Content-Length: 0 Date: Fri, 08 Aug 2025 00:45:40 GMT Server: lighttpd/1.4.71你帮我看看是不是我前端的问题 function sendAutoMKCOL() { const resultDiv = document.getElementById('mkcolResult'); // 初始状态 resultDiv.textContent = "正在发送MKCOL请求..."; resultDiv.style.backgroundColor = "#e0e0e0"; // 确保使用当前基础URL(带斜杠) const url = serverUrl; const xhr = new XMLHttpRequest(); xhr.open("MKCOL", url, true); xhr.setRequestHeader("Expect", ""); xhr.onload = function() { if (xhr.status >= 200 || xhr.status < 300) { // 201 Created(创建成功)或 405 Method Not Allowed(已存在)都可能是正常情况 // 但这里我们需要显示响应内容 resultDiv.textContent = `请求成功,状态码: ${xhr.status}\n响应内容:\n${xhr.responseText}`; resultDiv.style.backgroundColor = "#e8f5e9"; } else { resultDiv.textContent = `请求失败,状态码: ${xhr.status}\n${xhr.statusText}`; resultDiv.style.backgroundColor = "#ffebee"; } }; xhr.onerror = function() { resultDiv.textContent = "网络请求失败,请检查连接"; resultDiv.style.backgroundColor = "#ffebee"; }; xhr.send(); }
最新发布
10-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值