http请求详解_http请求头详解 - CSDN
精华内容
参与话题
  • 一次完整的HTTP网络请求过程详解

    千次阅读 2018-05-22 15:06:04
    简单地回答这个问题,大概是经历了域名解析、TCP的三次握手、建立TCP连接后发起HTTP请求、服务器响应HTTP请求、浏览器解析html代码,同时请求html代码中的资源(如js、css、图片等)、最后浏览器对页面进行渲染并...

    0.  前言

    从我们在浏览器的地址栏输入http://blog.csdn.net/seu_calvin后回车,到我们看到该博客的主页,这中间经历了什么呢?简单地回答这个问题,大概是经历了域名解析、TCP的三次握手、建立TCP连接后发起HTTP请求、服务器响应HTTP请求、浏览器解析html代码,同时请求html代码中的资源(如jscss、图片等)、最后浏览器对页面进行渲染并呈现给用户。下面分别介绍一下每个过程。

     

    1.  域名解析

    Chrome浏览器为例,Chrome会解析域名对应的IP地址

    1Chrome浏览器会首先搜索浏览器自身的DNS缓存(可以使用 chrome://net-internals/#dns 来进行查看),浏览器自身的DNS缓存有效期比较短,且容纳有限,大概是1000条。如果自身的缓存中存在blog.csdn.net 对应的IP地址并且没有过期,则解析成功。

    2)如果(1)中未找到,那么Chrome会搜索操作系统自身的DNS缓存(可以在命令行下使用 ipconfig /displaydns 查看)。如果找到且没有过期则成功。

    3)如果(2)中未找到,那么尝试读取位于C:\Windows\System32\drivers\etc下的hosts文件,如果找到对应的IP地址则解析成功。

    4)如果(3)中未找到,浏览器首先会找TCP/IP参数中设置的本地DNS服务器,如果要查询的域名包含在本地配置的区域资源中,则完成域名解析,否则根据本地DNS服务器会请求根DNS服务器

    5)本地DNS会把请求发至13台根DNS,根DNS服务器收到请求后会返回负责这个域名(.net)的服务器的一个IP,本地DNS服务器使用该IP信息联系负责.net域的这台服务器。这台负责.net域的服务器收到请求后,如果自己无法解析,会返回.net域的下一级DNS服务器地址(blog.csdn.net)给本地DNS服务器。以此类推,直至找到。

     

    2.  TCP的三次握手

    这个部分正好之前整理过,可以参考NetWork——关于TCP协议的三次握手和四次挥手

     

    3.  建立TCP连接后发起HTTP请求

    TCP三次握手建立连接成功后,客户端按照指定的格式开始向服务端发送HTTP请求,服务端接收请求后,解析HTTP请求,处理完业务逻辑,最后返回一个具有标准格式的HTTP响应给客户端。

     

    3.1  HTTP请求格式

    HTTP请求格式如下所示四部分组成,分别是请求行、请求头、空行、消息体,每部分内容占一行。

    [java] view plain copy
    1. <request-line>  
    2. <general-headers>  
    3. <request-headers>  
    4. <entity-headers>  
    5. <empty-line>  
    6. [<message-body>]  
    请求行:由三部分组成:分别是请求方法(GET/POST/DELETE/PUT/HEAD)、URI路径、HTTP版本号。

    请求头:缓存相关信息(Cache-ControlIf-Modified-Since)、客户端身份信息(User-Agent)等键值对信息。

    空行

    主体:客户端发给服务端的请求数据,这部分数据并不是每个请求必须的。

    常用的GETPOSTPUTDELETE四种请求方式中:

    1)关于GETDELETE将要处理的资源信息直接放在了URL。通过"?<键值对>&<键值对>“的形式追加。但是URL最大长度为1024字节。

    2)关于POSTPUT的请求参数存储在报文的主体中。每一个参数都以”--boundary值“+"属性信息"+”空行“+"参数值"的数据结构存储。请求数据的最后以”--boundary--“的格式结尾。

     

    3. 2  服务器响应HTTP请求

    服务器接收处理完请求后返回一个HTTP响应消息给客户端。HTTP响应消息的格式包括:状态行、响应头、空行、消息体。每部分内容占一行。

    [java] view plain copy
    1. <status-line>  
    2. <general-headers>  
    3. <response-headers>  
    4. <entity-headers>  
    5. <empty-line>  
    6. [<message-body>]  
    状态行:有HTTP协议版本号,状态码和状态说明三部分构成。

    响应头:用于说明数据的一些信息,比如数据类型、内容长度等键值对。

    空行

    消息体:服务端返回给客户端的HTML文本内容。或者其他格式的数据,比如:视频流、图片或者音频数据。

     

    4  浏览器解析html代码,并请求html代码中的资源

    浏览器拿到html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,向服务器端发起一个HTTP请求,如果服务器端返回304状态码(告诉浏览器服务器端没有修改该资源),那么浏览器会直接读取本地的该资源的缓存文件。否则开启新线程向服务器端去请求下载。(这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源。)

    最后,浏览器利用自己内部的工作机制,把请求到的静态资源和html代码进行渲染,再呈现给用户。


    展开全文
  • 什么是Http协议? HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程。客户端连上web服务器后,若想获得web服务器中...

    一. 什么是Http协议?

    HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程。客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一定的通讯格式,HTTP协议用于定义客户端与web服务器通迅的格式。

    二. HTTP1.0和HTTP1.1的区别

    HTTP协议的版本:HTTP/1.0、HTTP/1.1
      在HTTP1.0协议中,客户端与web服务器建立连接后,只能获得一个web资源。
      在HTTP1.1协议,允许客户端与web服务器建立连接后,在一个连接上获取多个web资源。

    三. Http请求方式

    3.1 分类

    Http请求方式有很多种,一般我们常用的有两种:get和post,当我们不特别指定时,默认get方式

    3.2 区别

    get:这种方式可以在url后直接带参数传递数据,但内容不能大于1k,传输速率快,但不安全,因为数据会在地址栏上显示,对于一些安全性比较高的数据例如密码等,不建议使用
    post:这种方式通过实体内容传递数据,安全性较高,但传输速率较慢(请求对列)

    四. Http请求

    客户端连上服务器之后,客户端通过浏览器向服务器发出一个请求,这个请求要遵循Http协议,所以称为Http请求。

    4.1 内容

    一个完整的HTTP请求包括如下内容:一个请求行、若干消息头、以及实体内容
    示例:
    在这里插入图片描述

    4.2 内容——请求行

    请求行中的GET称之为请求方式,上面提到过,这里详细说明。请求方式有:POST、GET、HEAD、OPTIONS、DELETE、TRACE、PUT,常用的有: GET、 POST
      用户如果没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器直接输地址访问,点超链接访问等都是get,用户如想把请求方式改为post,可通过更改表单的提交方式实现。
      不管POST或GET,都用于向服务器请求某个WEB资源,这两种方式的区别主要表现在数据传递上:如果请求方式为GET方式,则可以在请求的URL地址后以?的形式带上交给服务器的数据,多个数据之间以&进行分隔,例如:GET /mail/1.html?name=abc&password=xyz HTTP/1.1
      GET方式的特点:在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。
      如果请求方式为POST方式,则可以在请求的实体内容中向服务器发送数据,Post方式的特点:传送的数据量无限制。

    4.3 内容——消息头

    HTTP请求中的常用消息头:

    accept:浏览器通过这个头告诉服务器,它所支持的数据类型
      Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集
      Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式
      Accept-Language:浏览器通过这个头告诉服务器,它的语言环境
      Host:浏览器通过这个头告诉服务器,想访问哪台主机
      If-Modified-Since: 浏览器通过这个头告诉服务器,缓存数据的时间
      Referer:浏览器通过这个头告诉服务器,客户机是哪个页面来的 防盗链
      Connection:浏览器通过这个头告诉服务器,请求完后是断开链接还是何持链接
      示例:
      在这里插入图片描述

    展开全文
  • HTTP请求详解含POST,GET实例

    万次阅读 多人点赞 2018-05-05 21:45:55
    前言单纯的copy代码没有用,本篇从http请求的基本原理开始为大家讲解,后边有实例,希望大家一步一步看完,这样无论编写什么请求我们都可以得心应手。HTTP的组成http消息由客户端到服务端的请求以及服务端到客户端的...

    前言

    单纯的copy代码没有用,本篇从http请求的基本原理开始为大家讲解,后边有实例,希望大家一步一步看完,这样无论编写什么请求我们都可以得心应手。

    HTTP的组成

    http消息由客户端到服务端的请求以及服务端到客户端的响应组成

    HTTP请求报文的格式

    请求头与请求正文中间有一行空行,是告诉服务器请求头到此结束了接下来是请求正文

    请求方法:get,post,head,delete等等,告诉服务器你的具体操作是什么

    URL:可以从互联网上得到资源的位置和访问方法的一种简洁标识。URL结构:协议://域名 or IP地址:端口号/目录/文件名.文件名后缀?参数=值
    协议版本:目前几乎用的都是http1.1版本,增加了一个很重要的特性它支持长连接,其他具体细微差别不做讲述。
    请求头:请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔。
    常用的请求头包括:

    请求正文:添加请求实体即你具体要请求的内容用于POST请求,GET不用

    HTTP响应报文格式


    HTTP状态码


    HTTP响应头


    解析

    通过上述分析,我们可以发现HTTP请求其实像发送邮件一样,我们告诉邮局地址,邮局发送邮件,请求头是我们附加的一些信息,可以告诉收件人,谁发的邮件,谁可以看

    ,这是一封加密的邮件,你要根据什么规则把这封邮件翻译过来等等规则,请求内容当然就是我们要发送的具体内容,响应就是收件人给我的回信,响应头会告诉我们一些附加信息比如他告诉我们,你发送的那个收件人没有(404)或者我正确收到了你的来信(200),我给你的响应是什么加密方式,你要怎么解码,响应内容就是他要告诉我们的具体内容,你也可以把邮局当做一个代理,收件人当做服务器。

    实战

    接下来,我们根据以上规则使用JAVA来构造一些请求

    POST不带请求实体请求方法

    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.utils.URIBuilder;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.util.EntityUtils;
    
    public class TestHttp{
    	public void postOne(){
    		HttpClient client = new DefaultHttpClient();
    		HttpResponse response = null;
    		String url = "http://write.blog.csdn.net/postedit";
    		HttpPost post = new HttpPost(url);
    		post.setHeader("Content-Type", "application/json");
    		response = client.execute(post);
    		String	ret      = EntityUtils.toString(response.getEntity(),"UTF-8");
    		System.out.println(ret);
    }
    }
    解析:
    1,首先我们要构造一个客户端,apache对HttpClient这个类的解释是该接口仅表示HTTP请求执行的最基本合同,它不会对请求执行过程施加任何限制或具体细节,并且将状态管理,身份验证和重定向处理的细节留给个别实现。具体意思就是我们要发送HTTP请求就要先构造这个HTTPClient,但是涉及一些具体的细节比如cookies,header,request   body我们不需要用它来实现,这些具体的细节我们留给其他类来实现,
    2,我们构造一个请求地址,即我们要把这个请求发送给谁
    3,构建Post请求,HttpPost有一个构造器HttpPost(String uri) ,我们用这个构造器来初始化HttpPost
    4,添加header,HttpPost里有一个setheader和addheader方法,这些方法是它继承接口org.apache.http.HttpMessage得来的,这里说一下add和set的区别,首先同名header
    可以有多个,运行时使用第一个,当我们使用addheader时,如果同名header已经存在它会追加至原同名header后面,使用setheader时,他会覆盖同名的header,我在header
    中设定了我要发送的请求体是json形式的(实际上并未携带请求体,携带请求体的会在下边给例子)
    5,当我们构造好客户端,请求header,url地址后,此时就可以发送了,自然就是client.execute即执行这个请求
    6,接下来是接受响应,即我们发送完邮件后,别人给我们回信了,我们要设法获得这个回信的内容即HttpResponse response = client.execute(post) 来关联我们的请求和响应,意思就是这个响应是我执行这个请求的响应getEntity是这个类自带的方法,用来获取响应实体,即具体的响应内容,它还有很多方法,获取响应信息,感兴趣可以自行研究
    7,EntityUtils这个类主要是用来处理HttpEntity的,它有一些静态方法,我用的就是将这个响应实体以UTF-8的编码格式转换成字符串,最后打印出来

    具体响应

    <html><head><title>Object moved</title></head><body><h2>Object moved to <a href="https://passport.csdn.net/account/login?from=http%3a%2f%2fwrite.blog.csdn.net%2fpostedit">here</a>.</h2></body></html>
    解析:
    还有一些其他的内容,不在这里粘贴,返回的html代码是一个重新登录的地址链接,点击以后告诉我们重新登录,因为我访问的url是csdn的编辑页,不登录怎么可能直接访问呢,我们可以尝试使用cookie这里告诉大家一个进阶技巧,我们打开浏览器,启用开发者模式,然后重新登录一次,找到csdnbi这个接口,然后获取requestheader中的cookies
    具体如图:

    在这里找到cookie后我们使用post.setheader("Cookie","*****")就可越过登录,直接请求到这个页面了。感兴趣的可以试一下。

    具体响应

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>    <script type="text/javascript" src="//static-blog.csdn.net/scripts/tingyun-rum.js"></script><title>编辑文章 - CSDN博客</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <link type="text/css" rel="Stylesheet" href="http://c.csdnimg.cn/pig/blog/write/css/main.css" />    <!--new top-->        <link rel="stylesheet" href="http://c.csdnimg.cn/public/common/toolbar/css/index.css">     <!--new top-->       <script type="text/javascript" src="//static-blog.csdn.net/scripts/jquery.js"></script>    <script type="text/javascript" src="//static-blog.csdn.net/scripts/jquery-version.js"></script><script type="text/javascript" src="//static-blog.csdn.net/scripts/csdn.js"></script><script type="text/javascript" src="http://c.csdnimg.cn/pig/blog/write/scripts/master.js"></script>        <script type="text/javascript">var statichost = "//static-blog.csdn.net";</script>               <link type='text/css' rel='Stylesheet' href='http://c.csdnimg.cn/pig/blog/write/css/write.css' /><script type='text/javascript' src='http://c.csdnimg.cn/pig/blog/write/scripts/jquery.autocomplete.min.js'></script> <script type='text/javascript' src='//static-blog.csdn.net/xheditor/xheditor-1.1.13-zh-cn.js'></script><link type='text/css' rel='Stylesheet' href='http://c.csdnimg.cn/pig/blog/write/css/jquery.autocomplete.css' /></head><body></body></html>
    body里包含我的个人信息在这里就不给大家展示了

    POST带请求参数和请求实体

    前言:如果我们前边的都掌握了,那么接下来的就很容易理解了,我们知道post请求时会携带一些参数比如 http://www.123.com/index.html?a=123还有一些我们要发送的报文
    其实参数和报文的处理方式是一样的,那么我们只要构造这个请求实体不就可以了吗?
    		List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
    		nvps.add(new BasicNameValuePair("baowen","UTF-8"));
    		post.setEntity(new UrlEncodedFormEntity(nvps,"UTF-8"));

    解析:
    1,我们加入BasicNameValuePair,这个类是干嘛用的呢,apache的官方解释是用作HTTP消息元素的名称 - 值对参数。我们就用它来构造参数
    2,我为什么用list,因为有时你的参数可能不止一个,这是它的一个构造器BasicNameValuePair(String name, String value) ,报文一定要是字符串格式,UrlEncodedForm
      Entity(List<? extends NameValuePair> parameters, String charset) 我要用这个类来构造实体就必须使用list来添加参数,同时这个类实际上是继承StringEntity,它又实现了
    HttpEntity这个接口,知道这一点很重要。
    3,public void setEntity(HttpEntity entity)这个方法要传入一个HttpEntity类型的参数,所以后边我可以直接用。

    GET不带参数请求

    		HttpGet get = new HttpGet(url);
    		get.setHeader("Content-Type", "application/json");
    		HttpResponse rese = client.execute(get);
    		String redsa = EntityUtils.toString(rese.getEntity());

    GET携带参数请求

    		 CloseableHttpClient client3 = HttpClients.createDefault();
    		 List<NameValuePair> nvps2 = new ArrayList<NameValuePair>();
    		 nvps2.add(new BasicNameValuePair("baowen","213"));
    		 HttpResponse resep = null;
    		 URIBuilder builder = new URIBuilder(url);
    		 builder.setParameters(nvps2);
    		 HttpGet get21312 = new HttpGet(builder.build());
    		 response = client.execute(get21312);
    		 String sdf = EntityUtils.toString(response.getEntity(),"UTF-8");

    注意

    1,后边的代码我没有写完整,我们需要根据自己的需求添加URL
    2,header里我用的都是json,大家可以根据自己需要什么类型做改变
    3,我将返回都转换成了字符串,方便打印
    4,我这里使用的是apache的http包,关于网络编程,JAVA也有自带的java.net包

    总结

    通过上边的学习我们明白,只要我们掌握了http请求由什么组成,哪些类来构造这些东西,然后在解析响应剩下的就对我们来说很简单了。万变不离其宗,这次我发这个总结主要是由于之前发的一遍http 发送 post请求 的贴访问量很高,感觉有必要指引一下新入坑的同学们,当然我自己也在学习之中,欢迎大家留言,咱们互相探讨,共同进步












    展开全文
  • http基本请求详解

    千次阅读 2018-10-03 20:38:09
    自己总结的太短少,直接放上大佬总结的 Accept: 例: ...q=0.9,image/webp,image/apng,/;q=0.8 表示客户端支持的数据格式,或者说客户端“希望”接受到的内容类型。 这里只是希望,但是服务器具体返回什么样的内容...

    自己总结的太短少,直接放上大佬总结的

    Accept:
    例:
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
    表示客户端支持的数据格式,或者说客户端“希望”接受到的内容类型。
    这里只是希望,但是服务器具体返回什么样的内容类型,还是由服务器自己决定,但是无论服务器返回什么样的内容类型,客户端都会接收响应报文,不可能说因为内容类型不同,接收不到服务器响应报文,这不符合http协议规范。

    我们通过浏览器发起get或post请求,该字段都是浏览器自动添加的,同样在服务器端也不会解析该字段的值;
    通过ajax请求或其他手段,我们可以设置该字段的值,但是通常也不进行设置。

    该字段的应用场景可以是这样的,有两个终端,比如一个是纯文本阅读器,如Kinder(不能显示图片),另一个是移动终端(可以播放图片和视频),均向服务器请求有关“斑马”的信息,那么这时候服务器端就需要判断什么样的终端应该返回什么样的信息,那么它就可以根据Accept的信息来进行判断,如果解析到的Accept的值为“text/plain”,那么就表示客户端只支持文本类型;如果向上面例子中的那样,则表示客户端文本图片视频都可以。如果我们不加判断,当返回给文本阅读器一张图片时,可能它显示的就是乱码。

    Accept-Encoding:
    例:
    Accept-Encoding:gzip, deflate, br
    表示客户端所支持的解码(解压缩)格式。

    网路数据的传输都是占据带宽的,而将文件数据压缩能够降低数据量,减少传输时间。所以服务器在返回数据给客户端时,常常对数据进行压缩(对用户透明,通常由服务器或代理来做),而压缩的方式有多种,到底采用哪一种则需要看客户端支持哪种解码方式,这时候就可以根据header中Accept-Encoding的值。

    文件或数据的压缩,由服务器或代理来做,一般不需要程序员干预;客户端接收到数据时解压缩,通常由浏览器自动完成,对用户透明。
    对于我们主动发起的ajax请求,一般数据量较少,不需要设置该字段。

    Accept-Language:

    Accept-Language:zh-CN,zh;q=0.9
    表示客户端支持的语言格式(不是编码格式),如中文/英文,通常浏览器直接发起请求时,浏览器会根据被设置的语言环境(默认语言),来附加上该字段。

    一般我们服务器解析报文时,是不理会该字段的。
    他的使用场景可以是这样的,假如有个文件,有各种语言的版本,这样当不同请求发来时,我们可以根据Accept-Language的值来判断到底返回哪种语言版本给客户端。
    (其实这种应用场景也一般不采用判断Accept-Language字段的方法,不靠谱,还不如直接在url中体现语言版本呢)

    Accept-Charset:
    例:
    Accept-Charset:gbk,utf-8;q=0.8
    表示客户端支持编码格式。服务器在返回报文时,需要将字符按照一定的编码格式转换为字节序列发送给客户端,那么该采用哪种编码格式呢?
    当然作为服务器端,他可以采用任何一种编码方式,客户端都得完完整整的接收响应报文。因为目前客户端几乎都支持常见编码类型,所以服务器在返回数据时,只需要按照既定的编码方式编码,然后在响应报文中告知客户端所使用的编码方式。这样客户端在接收到报文后按照该方式进行解码,就就不会出现乱码问题。

    但是,如果客户端已经定了就使用某种解码方式,那么这时候服务器端就不能那么任性了,他就需要解析Accept-Charset字段,根据这个值,来设定采用的编码方式。
    如上例中,以逗号分隔,客户端支持两种编码方式,gbk和utf-8(gbk优先级高于utf8),其中utf-8后的q值,表示utf-8占的“权重”。


    题外话:
    服务器端怎么通知浏览器所采用的编码格式呢?
    如果不通知浏览器,那么浏览器会采用什么样的格式解码呢?

    服务器端以原生的Servlet & JSP为例:
    1)当返回的是HTML页面,那么页面meta charset就指定了编码格式
    2)当返回的是JSP页面,那么页面pageEncoding就指定了编码格式
    3)当通过resp的Outputstream返回原生内容时,我们可以通过设置响应头content-type/content-charset字段来指定编码格式

    那么如果服务器不指定编码格式呢?
    我的测试环境为win10中文操作系统,浏览器:Chrome 64.0.3282.186(正式版本)

    1)返回的html页面不设置meta标签,但是文件本身是utf-8或gbk编码,中文不乱码,
    服务器会将html页面转换为字节流写给浏览器,浏览器读取字节流,由于找不到meta标签设置的文件格式,就会按照默认的格式解码。

    这时出现的情况是,当原页面是gbk编码时,浏览器能正常显示页面;当原页面是utf-8编码时,浏览器显示中文乱码。

    这说明当前Chrome浏览器的默认编码格式为gbk。使用微软自带的Microsoft Edge测试结果一样 。

    2)返回JSP页面时,必须指定pageEncoding。

    3)通过response的输入流,直接返回生成的字节流(GBK格式的),此时,不设置响应头的编码格式。

    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //resp.setContentType("text/html;charset=gbk");
            resp.setContentType("text/html;");
            ServletOutputStream out = resp.getOutputStream();
            out.write("<h1>好好学习</h1>".getBytes("gbk"));
            out.close();
    
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1、直接在浏览器地址栏输入访问地址,不乱码

    这里写图片描述
    2、通过ajax发送get请求,乱码

    var xhr = new XMLHttpRequest();
    xhr.onload = function (argument) {
         if(xhr.readyState==4){
            alert(xhr.responseText);//打印接收的字符串
         }
    }
    xhr.open('get','http://localhost:8080/mvctest/http',true);
    xhr.send(null);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里写图片描述

    当服务器使用gbk编码返回字节流时,地址栏的http请求不乱码,但是ajax请求响应乱码;
    如果我们的服务器使用utf-8返回字节流时,地址栏的http请求乱码,但是ajax不乱码。
    (第二种测试结果贴图省略)

    这说明同一个浏览器,在不同的地方采用的编码格式不同,当浏览器解析页面时,它默认使用的是gbk编码(可能因为我们的中文操作系统,同时是中文版的软件,所以浏览器默认使用gbk格式来解析页面);当浏览器使用内核XMLHttpRequest对象来解析响应时,默认采用的是utf-8(这个应该跟操作系统语言没关系,内核层面的应该在哪个国家都一样)

    所以,如果为了确保在各种情况下都不乱码,服务器一定要通知客户端所采用的编码格式


    我们继续来说头字段的含义:

    Referer:
    例:
    Referer:http://localhost:8080/test/11.html
    表示当前请求是从哪个资源发起的;或者是请求的上一步的地址。
    我在11.html页面发起一个请求,这时候浏览器封装的请求头就有上例中的referer字段,表示当前请求是这个资源链接中发起的。
    这里写图片描述

    Referer是常用于网站的访问统计,比如我在很多地方都做了广告链接到我网站的主页,这时候我就可以通过Referer来查看哪些地方跳转过来的人多,就说广告的效果好。
    另外,Referer还经常用于防盗链,具体可以参见这位兄台博客“http防盗链”

    If-Modified-Since:
    例:
    If-Modified-Since:Thu, 29 Mar 2018 08:37:45 GMT
    表示客户端缓存文件的时间。字面翻译的意思是,“如果从…时间改变了”(就请再发送给我一遍新的文件)。

    当客户端访问服务器的静态文件时,通常会将资源结果缓存下来,并标记一下文件的缓存时间(根据响应头中的Last-Modified字段);当接下来再发送同样的请求时,会在请求头中添加上这个字段If-Modified-Since;

    服务器端读取字段值,判断服务器端文件的最后修改时间,如果如果不晚于该值,说明浏览器缓存的文件是最新的,然后就不会重新发送文件内容,而是将相应报文的状态设置为304,表示你读取缓存的文件就可以了,这就很大程度上节省了带宽。
    第一次请求头:

    GET /mvctest/11.html HTTP/1.1
    Host: localhost:8080
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    第一次响应头:
    这里写图片描述

    第二次请求头:
    这里写图片描述
    第二次响应头:
    这里写图片描述

    需要说明的是,If-Modified-Since字段的值,为服务器端文件最后修改的时间,不是请求的访问时间,时间值为GMT格林尼治时间,不是本地时间。
    浏览器一般只对.html,.jpg,.css,.js等这些静态资源进行缓存,对于jsp页面以及ajax请求的动态结果,不缓存。服务器如Tomcat会自动给静态文件的响应报文添加“Last-Modified”字段,同时解析请求报文中的If-Modified-Since字段,这些都是对我们透明的。

    例如,我们将11.html改为11.jsp,那么浏览器将不会缓存页面内容,服务器每次都响应一个完整的页面内容给客户端,也不会在响应报文中添加“Last-Modified”字段。
    每次对于JSP请求的响应结果:
    这里写图片描述

    If-None-Match:
    例:
    If-None-Match:W/”607-1522312665174”
    该字段同If-Modified-Since字段一样,都是用来表示资源文件是否是最新的。只不过If-Modified-Since的值为文件的最后修改时间,而该值为资源实体的哈希值,同样是由服务器生成的
    从上面的截图中我们可以看到:
    第一次请求时,服务器的响应报文中有字段Etag,这就是实体的哈希值,浏览器会缓存文件并记录该值。
    第二次请求时,请求头字段中就有If-None-Match,值为Etag的值,而服务器会判断该值与服务器中文件的哈希值是否相同,如果相同,就返回304,让浏览器读取缓存;否则会返回新的资源文件,并在响应头中设置新的Etag值。

    Last-Modified/If-Modified-Since 和 Etag/If-None-Match这两对头字段都是来标记缓存资源的,但是后者的优先级要高于前者。

    Cache-Control:
    例:
    Cache-Control:no-cache
    字段的字面意思为“缓存-控制”,前面我们将了几个字段表面客户端/服务器如何使用缓存机制,而这个字段就是用来控制缓存的。

    Cache-Control在请求/响应报文头中均可设置,分别表明不同的意思,下面我们以响应报文为例:cache-control在响应报文的的取值可以为:public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。
    所代表的意思为:
    这里写图片描述
    其中,no-cache、no-store、max-age为常用的取值。
    比如,服务器在响应报文中添加Cache-Control:no-store,表示浏览器或各级代理,不要缓存本次的相应内容(即使响应报文中有Etag和Last-Modified);

    比如,响应报文中有Cache-Control:no-cache,表示浏览器可以缓存响应文件,但是在使用缓存之前,必须通过令牌(Etag)来与服务器进行沟通确认缓存有效。

    比如,响应报文中有Cache-Control:max-age=500,表示在接下来的500秒内,浏览器可以自主使用缓存内容,不需要向服务器发送同样的请求。

    在请求报文中,也可以添加cache-control字段,其取值可以为no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached。
    客户端在发送请求到服务器时,可能会经过很多层代理,而这些代理可能就缓存了本次请求想要的文件,而请求中的cache-control就可以控制,是否使用代理中的缓存文件。

    比如,请求报文头中有cache-control:no-cache,那就表示,代理如果返回给我缓存文件时,需要到服务器端进行确认,缓存是不是最新的。

    比如,请求报文头中有cache-control:no-store,那就表示,我不需要代理中的缓存文件,我需要直接请求服务器。

    所以我们可以看到,cache-control就是用来控制缓存使用的,如是否缓存,是否使用缓存,缓存到期时间等,而Last-Modified/If-Modified-Since 和 Etag/If-None-Match是标识C/S之间怎么使用缓存。
    缓存的使用都是服务器和客户端的默认行为,对用户和程序员的透明的,当然我们可以通过配置文件或程序修改他们的行为规则。
    附:http协议中对缓存的说明

    User-Agent:
    例:
    User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
    表示客户端的软件环境。如上可以看出使用的是Window10 64位操作系统,Chrome浏览器等信息。服务器可以根据该字段评估客户端的环境从而给出不同的响应。(比如根据请求是从手机端或是电脑端发起的,返回不同版本的页面)

    Host:
    例:
    Host:localhost:8080
    表示请求者的主机地址(IP地址)和端口号。
    服务器端可以根据该字段进行ip过滤等操作。


    响应头
    Etag、Last-Modified、cache-control在前文中已经说明。

    Content-Length:
    例:
    Content-Length:607
    表示接收到的响应报文的总长度为607。
    根据这个长度,客户端可以更准确的接收和解析报文内容。或者可以根据当前接收/解析的长度占总长度的百分比,做出进度条的效果。

    Accept-Ranges:
    例:
    Accept-Ranges:bytes
    表示服务器支持http中的Range功能,能够分段请求客户端能够分段请求服务器。
    我们上网时常用的“断点续传”,或者服务器所谓的“多线程下载”就是靠的服务器端的Range技术。
    Range功能的请求-响应流程如此:
    客户端发起带range的请求:

    GET  /test.rar  HTTP/1.1
    Connection:  close
    Host:  116.1.219.219
    Range:  bytes=0-100
    • 1
    • 2
    • 3
    • 4

    在头中添加Range字段,表示我要请求[0-100]这101个字节的数据。
    此处Range的值,可以添加多个片段,如 Range:bytes=0-100,200-300等。

    服务器响应报文:

    HTTP/1.1 206 OK
    Content-Length:  801     
    Content-Type:  application/octet-stream 
    Content-Location: http://www.onlinedown.net/hj_index.htm
    Content-Range:  bytes  0-100/2350        //2350:文件总大小
    Last-Modified: Mon, 16 Feb 2009 16:10:12 GMT
    Accept-Ranges: bytes
    ETag: "d67a4bc5190c91:512"
    Date: Wed, 18 Feb 2009 07:55:26 GMT
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    响应报文中有Content-Range字段,表示响应的报文片段内容范围,已经总的数据大小。
    同时Range请求的正常的返回码是206,不是200。

    而即使我们请求的不是Range功能请求,那么服务器的返回字段中会有Accept-Range,表示服务器支持Range功能。

    Server:
    例:
    Server: Apache/2.4.1 (Unix)
    表示服务器的名称,是Unix下的Apache服务器

    --------------------- 本文来自 Boboma_dut 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/Boboma_dut/article/details/79741162?utm_source=copy

    展开全文
  • Http请求详解

    2019-07-08 23:30:59
    1. HTTP请求格式 首先介绍HTTP协议:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。 工作原理: 由HTTP客户端发起一个请求,...
  • HTTP请求行、请求头、请求体详解

    万次阅读 多人点赞 2017-03-30 19:09:22
    HTTP请求
  • HTTP请求各参数详解

    万次阅读 2019-05-14 09:52:45
    1、HTTP请求方式 如下表: GET 向Web服务器请求一个文件 POST 向Web服务器发送数据让Web服务器进行处理 PUT 向Web服务器发送数据并存储在Web服务器内部...
  • JMeter之聚合报告参数详解

    万次阅读 2018-01-08 16:03:37
    Label----每个请求的名称,比如HTTP请求等 #Samples----发给服务器的请求数量 Average----单个请求的平均响应时间 Median----50%请求的响应时间 90%Line----90%请求响应时间 95%Line----95%请求响应...
  • Java中http的GET和POST请求详解

    千次阅读 2018-02-06 15:57:29
    Java中http的GET和POST请求详解 1. http get/post方法(使用传统的URL connection方法,JDK自带):  (1) GET请求:(向服务器发送访问数据的请求,从而获取数据),(类似数据库中的select操作),(不会...
  • HttpServletRequest详解

    万次阅读 多人点赞 2020-06-09 11:12:15
    HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。 获得客户机信息: ...
  • HTTP协议格式详解(总结)

    万次阅读 2019-05-09 23:20:17
    认识url url:就是我们平时说的“网址” HTTP协议格式 HTTP请求响应机制 ...响应请求并断开连接 应用层核心工作: 把数据通过 TCP 实现从A点到B点,但是从A——>B只是最基础阶段,它后续要对HT...
  • GET 和 POST 请求的区别

    万次阅读 2004-08-27 11:25:00
    关于你上次提到的问题:// --TCP/IP 协议详解卷313.3.1 报文类型:请求与响应HTTP / 1 . 0报文有两种类型:请求和响应。HTTP / 1 . 0请求的格式是:reqe t - l i n eheaders ( 0或有多个)body (只对POST请求有效)...
  • 详解HTTP GET请求

    千次阅读 2019-12-17 11:55:40
    实例1:NodeMcu通过TCP实现HTTP GET请求(无请求主体)srv = net.createConnection(net.TCP, 0) srv:on("receive", function(sck, c) print(c) end) srv:connect(80,"fanyi.youdao.com") srv:on("connection", ...
  • HTTP 结构详解

    万次阅读 2020-09-18 11:42:22
    一个HTTP请求由请求行、请求头、空行和请求数据4个部分组成。 1.1 请求行 由三部分组成,请求方法、请求URL(不包括域名)、HTTP协议版本。 1.1.1 请求方法 GET:传递参数长度受限制,因为传递的参...
  • QT Http GET POST QHttp详解

    千次阅读 2013-07-23 14:15:57
    QT Http GET POST QHttp详解 请求请求头类:QHttpRequestHeader 设置 [...] QT Http GET POST QHttp详解 请求请求头类:QHttpRequestHeader 设置请求方式(get/post) 1 ...
  • 1、下载软件Fiddler 下载链接地址为:...下载完成 之后,傻瓜式地安装一下就可以了。 我安装的版本为:v4.6.20171.14978 ...打开Fiddler,Tools -> Telerik Fiddler Options(配置完记得重启) ...
  • nginx内置变量详解

    万次阅读 2016-11-11 12:21:29
    例如:负载均衡中的header头转发 让后端服务器可以获取到客户端请求的真实ip  首先我们来先看一个最基本的请求header 请求www.baidu.com 最简单的一个get请求 请求了一个aaa的关键字 请求header如下
  • SSM框架详解(非原创)

    千次阅读 2018-01-18 10:19:10
    springMVC的工作原理:1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet。2、...
  • 跨域CORS头信息详解

    万次阅读 2020-06-13 17:31:48
    指示当请求的凭证标记为 true 时是否响应该请求。 Access-Control-Allow-Headers 用在对预请求的响应中,指示实际的请求中可以使用哪些 HTTP 头。 Access-Control-Allow-Methods 指定对预请求的响应中,哪些 ...
  • get和post详解

    千次阅读 2018-11-23 22:24:52
    Get和post是表单提交数据的两种基本方式,get请求数据通过域名后缀url传送,用户可见,不安全,post请求数据通过在请求报文正文里传输,相对比较安全。 get是通过url传递表单值,post通过url看不到表单域的值; ...
1 2 3 4 5 ... 20
收藏数 155,345
精华内容 62,138
关键字:

http请求详解