论HTTP请求大小

HTTP分为URI,HEADER,Body三个部分。每个部分都可以包含请求信息,那么每个部分是否都有请求大小限制呢?刚开始以为这个问题很容易找到答案,后来发现这也是个挺复杂的问题。

URI

首先是URI,我们知道,在GET请求中,请求参数是放在URL进行传递的,所以,HTTP GET的请求最关心的一个问题:能有多长?我能放多少参数?URI

从HTTP 1.1协议中开始找:(RFC 2616)

The HTTP protocol does not place any a priori limit on the length of a URI

所以明确一点的是HTTP协议是没有显式限制URI的长度的。理论上来说你在URI中传递多少参数都是可以的。

 

但是现实往往无法永远照进阳光:

1 浏览器限制

所有主流浏览器都会对URI的长度进行限制。如果你在浏览器中输入过长的URI,那么浏览器会自动进行截断。各个浏览器对URI长度的限制各不相同,甚至不同版本也不一样。大约一个概念,2000字符以内的URI都能符合所有主流浏览器的要求。

2 服务端限制

即使客户端同意发送无限长度的URI,但是服务器一方一般都是有长度限制的。一般服务是没有专门针对URI的参数限制的,但是由于URI是会包含在request header中的,所以对header的大小限制是会对URI起作用的,比如nginx的(large_client_header_buffers)这个属性,它默认是4k。

 

题外话

这里的“URI是包含在request header中的” 这句话其实是有问题的。URI在HTTP协议中是叫做request-Line的,如果具体看协议,是会发现request-Line和request-header是两个不一样的,就是说request的请求其实该分为request-line,request-header,request-body三个部分的(具体可以看http://www.ietf.org/rfc/rfc2616.txt 第4和5章)。但是好像使用的时候都默认将header中理解为包含了request-line(比如这篇文章http://trafficserver.apache.org/docs/v2/sdk/HTTPHeaders.html)。这里估计是概念和使用的时候导致问题,不必深究了,所以我们不妨将request-line理解为包含在header中就好。

 

不管如何,综上所述,这里的URI不论是客户端还是服务端,基本是被默认限制住的。

Header

header中存放的信息非常多,比如request-line,cookie,还有各种key-value的特定header字段和值。有点时候,我们也会往header中添加一些自定义的属性。header的长度和URI的情况是一样的。协议中并没有显示限制header的大小。理论上在header中放多少属性都是可以的。

但是实际上:

1 浏览器限制

各个主流浏览器限制几十k~几百M不等的限制。基本上能满足平时的需求了。但是如果这个长度对你业务有很大影响的话,建议还是亲自测试下。

2 服务端限制

比如nginx的large_client_header_buffers就限制了header的长度。你也可以自己设置。

 

可能会影响header的参数还有:

client_header_buffer_size

client_header_timeout

各参数可以参考:http://wiki.nginx.org/HttpCoreModule

Body

body和URI,header非常不一样,不一样的地方原因在于文件上传。HTTP是支持request中带文件的,那么文件的二进制数据不会放在URI或者header里面,它是放在body里面的。那么这个body的大小就一定不能默认限制太小,尤其是客户端。

 

首先理论上,协议是没有对body大小做任何限制的。

其次,浏览器也没有对body做任何大小限制,因为如果浏览器做了大小限制就意味着它直接影响了你的服务功能。

所以对body的限制的任务就放在了服务器上了。这里就我最熟悉的nginx+php-fpm来看下有哪些地方可以对body进行限制:

1 nginx有一些设置会对body大小产生影响

client_max_body_size,这个参数可以限制body的大小,默认是1m

client_body_timeout,当body太大,或者网络太差的时候,这个也有可能会影响请求的成功率的。

2 php.ini也有一些设置会对上传的body数据产生影响

upload_max_filesize,限制最大上传文件大小

post_max_size ,限制post的大小

memory_limit,限制内存使用大小

max_execution_time,这个是php最大执行时间,也有可能影响请求成功率的。

HTTP请求大小有什么影响

首先是安全因素考虑。

试想一下一个网站的服务器是不限制body大小的,那么它就是可以被黑客利用攻击的地方了。黑客利用这一点往HTTP POST的body中传递非常大(比如几M)的请求。那么比如像nginx+php-fpm这样的,就会占用了服务器一个php进程专门处理这个请求,就会导致你对外无法提供其他的服务了,你的服务就瘫痪了,这就是DDOS攻击。

其次是文件上传服务考虑。

文件上传有两种情况:

你可能经常遇到为什么文件上传失败?那么大多是上文说的几个设置没有设置对。

其次,文件上传大小是不是设置越大越好?答案必须是否定的,理由也是安全考虑。满足需求的大小限制就够了。

这里就可以理解为什么大都把文件上传和业务接口分开来提供了吧。如果你的文件上传服务和业务接口是同一个机器的话,那么就说明你的业务接口可以允许的body大小一定是很大的。换句话说,在这种情境下,你的业务中的所有POST请求都是不安全的!!只要进行DDOS攻击,业务就会瘫痪。

 

附 GET VS POST:

1、多数浏览器对于POST采用两阶段发送数据的,先发送请求头,再发送请求体,即使参数再少再短,也会被分成两个步骤来发送(相对于GET),也就是第一步发送header数据,第二步再发送body部分。HTTP是应用层的协议,而在传输层有些情况TCP会出现两次连结的过程,HTTP协议本身不保存状态信息,一次请求一次响应。对于TCP而言,通信次数越多反而靠性越低,能在一次连结中传输完需要的消息是最可靠的,尽量使用GET请求来减少网络耗时。如果通信时间增加,这段时间客户端与服务器端一直保持连接状态,在服务器侧负载可能会增加,可靠性会下降。

Tips:关于这点你可以参考:Yahoo网站性能优化指南之服务器篇

http://segmentfault.com/a/1190000000353790

 

http://developer.yahoo.com/performance/rules.html

http://blogread.cn/it/article/6100?f=wb    YSLOW法则中,为什么yahoo推荐用GET代替POST?

上面这篇文章介绍了 wireshark 抓包验证 post 两次发包,get 一次发包的全过程,推荐阅读。

 

 

2、GET请求能够被cache,GET请求能够被保存在浏览器的浏览历史里面(密码等重要数据GET提交,别人查看历史记录,就可以直接看到这些私密数据)POST不进行缓存。
 

3、GET参数是带在URL后面,传统IE中URL的最大可用长度为2048字符,其他浏览器对URL长度限制实现上有所不同。POST请求无长度限制(目前理论上是这样的)。
 

4、GET提交的数据大小,不同浏览器的限制不同,一般在2k-8K之间,POST提交数据比较大,大小靠服务器的设定值限制,而且某些数据只能用 POST 方法「携带」,比如 file。
 

5、全部用POST不是十分合理,最好先把请求按功能和场景分下类,对数据请求频繁,数据不敏感且数据量在普通浏览器最小限定的2k范围内,这样的情况使用GET。其他地方使用POST。

6、GET 的本质是「得」,而 POST 的本质是「给」。而且,GET 是「幂等」的,在这一点上,GET 被认为是「安全的」。但实际上 server 端也可以用作资源更新,但是这种用法违反了约定,容易造成 CSRF(跨站请求伪造)。

 

对nginx处理header时的方法:
  1. 先处理请求的request_line,之后才是request_header。
  2. 这两者的buffer分配策略相同。
  3. 先根据client_header_buffer_size配置的值分配一个buffer,如果分配的buffer无法容纳 request_line/request_header,那么就会再次根据large_client_header_buffers配置的参数分配large_buffer,如果large_buffer还是无法容纳,那么就会返回414(处理request_line)/400(处理request_header)错误。
  1. 如果你的请求中的header都很大,那么应该使用client_header_buffer_size,这样能减少一次内存分配。
  2. 如果你的请求中只有少量请求header很大,那么应该使用large_client_header_buffers,因为这样就仅需在处理大header时才会分配更多的空间,从而减少无谓的内存空间浪费。

针对get请求,解决请求串过长的问题:

 

针对get请求,我们可以通过修改另外两个配置来解决请求串超长的问题:client_header_buffer_size语法:client_header_buffer_size size默认值:1k使用字段:http,server这个指令指定客户端请求的http头部缓冲区大小绝大多数情况下一个头部请求的大小不会大于1k不过如果有来自于wap客户端的较大的cookie它可能会大于1k,Nginx将分配给它一个更大的缓冲区,这个值可以在large_client_header_buffers里面设置。large_client_header_buffers语法:large_client_header_buffers number size默认值:large_client_header_buffers 4 4k/8k使用字段:http,server指令指定客户端请求的一些比较大的头文件到缓冲区的最大值,如果一个请求的URI大小超过这个值,服务器将返回一个"Request URI too large" (414),同样,如果一个请求的头部字段大于这个值,服务器将返回"Bad request" (400)。缓冲区根据需求的不同是分开的。默认一个缓冲区大小为操作系统中分页文件大小,通常是4k或8k,如果一个连接请求将状态转换为keep-alive,这个缓冲区将被释放。

 

参考文章

http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers

http://www.boutell.com/newfaq/misc/urllength.html

http://stackoverflow.com/questions/3326210/can-http-headers-be-too-big-for-browsers

http://admirestator.diandian.com/post/2012-04-28/19237704

https://www.cnblogs.com/zxwBj/p/8689962.html

https://www.cnblogs.com/jpfss/p/10237624.html

原文地址:https://blog.csdn.net/thlzjfefe" target="_blank" rel="noopener" title="thlzjfefe">thlzjfefe</a> <img class="article-time-img article-heard-img" src="https://csdnimg.cn/release/blo

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读3.7k次,点赞2次,收藏5次。Nginx学习笔记一、Nginx 简介1. 什么是Nginx2. 反向代理3. 负载均衡4. 动静分离二、Nginx基本使用1. Nginx常用的操作命令2. Nginx的配置文件提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、Nginx 简介1. 什么是Nginx2. 反向代理3. 负载均衡4. 动静分离二、Nginx基本使用1. Nginx常用的操作命令2. Nginx的配置文件一、Nginx 简介1. 什么是Nginx  Nginx(“engine x”)是一个_nginx代理
文章浏览阅读1.7w次,点赞14次,收藏61次。我们在使用容器的过程中需,有时候需要对容器中的文件进行修改管理,如果不做文件映射的化,我们使用docker exec -it 容器ID/容器名 /bin/bash 才能进入nginx中的文件里面如图。架设在客户机与目标主机之间,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将原本要直接发送到web服务器上的http请求发送到代理服务器中。A想要组C的房子,但是A并不认识C所以租不到,但是B认识C,A找B帮忙租到了C的房子。客户端代理服务器服务器。_docker nginx 配置
文章浏览阅读1.4k次。当用户在访问网站的过程中遇到404错误时,通常情况下应该显示一个友好的错误页面,而不是仅仅显示一个简单的错误提示。在Nginx中,可以通过配置来实现404错误自动跳转到首页的功能。如果您的网站使用动态内容生成页面(如PHP或其他服务器端语言),则应相应地修改配置以适应您的网站架构。这样,当用户访问一个不存在的页面时,Nginx会自动将其重定向到首页。为了使配置生效,需要重新加载Nginx配置。首先,需要打开Nginx的配置文件。现在,当用户访问一个不存在的页面时,Nginx会自动将其重定向到首页。_nginx 404 重定向
文章浏览阅读2.7k次。docker 和 docker-compose 部署 nginx+mysql+wordpress 实战_docker wordpress mariadb
文章浏览阅读1.3k次。5:再次启动nginx,可以正常启动,可以在任务管理器中查看到nginx的进程。重新启动下 直接访问8090端口 ok 访问成功。1 :查看80端口占用情况,pid的值为3960。3:在运行中输入regedit打开注册表编辑器。2: 通过以下命令查看3960所对应的服务名称。4:找到Start,右键修改将其制改为4。_nginx80端口无法访问
文章浏览阅读3.1w次,点赞105次,收藏182次。高性能:Nginx 被设计为能够处理大量并发连接而不显著增加系统负担。它采用异步事件驱动的架构,可以有效地处理高流量的 Web 请求。负载均衡:Nginx 支持负载均衡,可以将请求分发到多个后端服务器,以提高网站性能和可用性。反向代理:Nginx 可以充当反向代理,将客户端请求转发到后端服务器,隐藏后端服务器的真实 IP 地址,增加安全性和可扩展性。静态文件服务:Nginx 可以高效地提供静态文件(如 HTML、CSS、JavaScript、图像等)的服务,减轻应用服务器的负担。
文章浏览阅读976次。nginx作为常用的web代理服务器,某些场景下对于性能要求还是蛮高的,所以本片文章会基于操作系统调度以及网络通信两个角度来讨论一下Nginx性能的优化思路。我们的大学教程大部分讲述七层模型,实际上现代网络协议使用的都是四层模型,如下图,应用层报文经过四层的首部封装到对端。对端链路层拆开首部查看mac地址是自己在网上,拆开ip首部查看目的地址是不是自己,然后到达传输层应用层完成报文接收。文章是基于原有个人知识基础上,对旧知识进行巩固,以及新知识实践学习。
文章浏览阅读5.4k次,点赞9次,收藏15次。最后再说一种情况,就是后端处理了跨域,就不需要自己在处理了(这里吐槽下,某些后端工程师自己改服务端代码解决跨域,但是又不理解其中原理,网上随便找段代码黏贴,导致响应信息可能处理不完全,如method没添加全,headers没加到点上,自己用的那个可能复制过来的并不包含实际项目所用到的,没有添加options请求返回状态码等,导致Nginx再用通用的配置就会可能报以下异常)里面的就好了,因为这里如果是预检请求直接就ruturn了,请求不会再转发到59200服务,如果也删除了,就会报和情况1一样的错误。_nginx 允许跨域
文章浏览阅读2.5k次。项目配置了多个域名,如下,php 代码中有获取的值。当访问a.demo.com时,其获取的值是符合预期的。但是当访问b.demo.com时,其获取的值还是a.demo.com,导致代码中的判断出现错误。_nginxservername多个域名
文章浏览阅读1k次,点赞2次,收藏5次。采用YAML manifest的方式来安装ingress-nginx,用registry.lank8s.cn镜像库来替换 registry.k8s.io的库。_ingress-nginx安装
文章浏览阅读1.6k次,点赞2次,收藏2次。在windows平台编译nginx_windows 编译nginx
文章浏览阅读5.8k次,点赞2次,收藏18次。nginx [engine x] 是 HTTP 和反向代理服务器、邮件代理服务器和通用 TCP/UDP 代理服务器。nginx 的特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。在高连接并发的情况下,nginx是Apache服务器不错的替代品,能够支持高达50000个并发连接数的响应。使用epoll and kqueue作为开发模型。_nginx
文章浏览阅读2k次。Linux启动(systemctl start nginx)nginx服务时出现:Failed to start nginx.service: Unit not found._为什么nginx的systemctl start nginx.service不能使用
文章浏览阅读1.3k次。重启之后,打开浏览器,输入http://localhost:8900/myBaidu,这时候就会自动的跳转到百度的页面。按照我们不同的需求修改nginx文件夹中的nginx-1.16.1conf里面的nginx.conf文件。启动nginx:打开nginx的文件夹,然后双击nginx.exe文件,启动nginx。打开之后假设我们需要跳转到百度则在配置文件nginx.conf中的下面加上。1、打开任务管理器关闭nginx的进程。端口在配置文件的(下图)进行查看nginx端口。_nginx 代理百度
文章浏览阅读5.7k次,点赞5次,收藏3次。nginx重定向问题解决(rewrite or internal redirection cycle)_rewrite or internal redirection cycle while internally redirecting to "/inde
文章浏览阅读1.3k次。请注意,上述命令假设 Nginx 已经在系统的 PATH 环境变量中配置。如果没有,请提供正确的 Nginx 安装路径,或者在命令中使用完整的路径来替换。将该命令与所有 Nginx 进程的 PID 一起使用,以终止所有正在运行的 Nginx 进程。此命令将启动一个新的 Nginx 进程来重新加载配置文件并重新启动服务器。使用以下命令来终止所有 Nginx 进程(使用上面的 PID 替换。的进程以及它们的 PID。打开命令提示符(CMD)。此命令将列出所有名为。选项来强制终止进程。_windows 怎么关闭nginx
文章浏览阅读2.7k次,点赞2次,收藏7次。包括 Netflix、GitHub 和 WordPress。Nginx 可以用作 Web 服务器、负载均衡器、反向代理和 HTTP 缓存等。_ubuntu安装nginx
文章浏览阅读915次。轻松搭建短域名短链接服务系统,可选权限认证,并自动生成证书认证把nginx的http访问转换为https加密访问,完整步骤和代码。_nginx 短链代理
文章浏览阅读1.1k次,点赞35次,收藏24次。流媒体方案之Nginx——实现物联网视频监控项目Nginx是什么Nginx在流媒体方案中的位置软硬件准备移植编译Nginx运行Ngnix测试流媒体方案浏览器播放_nginx-rtmp-module
文章浏览阅读1.9k次。nginx 配置 wss 协议转发 ws 服务器_nginx 配置wss