linux 浏览器请求_linux 模拟浏览器请求 - CSDN
  • 1.elinks - lynx-like替代角色模式WWW的浏览器 例如:  elinks --dump http://www.baidu.com 2.wget 这个会将访问的首页下载到本地 [root@el5-mq2 ~]# wget http://www.baidu.

    1.elinks - lynx-like替代角色模式WWW的浏览器

    例如:

     elinks --dump http://www.baidu.com

    2.wget 这个会将访问的首页下载到本地

    [root@el5-mq2 ~]# wget http://www.baidu.com
    --2011-10-17 16:30:10--  http://www.baidu.com/
    Resolving www.baidu.com... 119.75.218.45, 119.75.217.56
    Connecting to www.baidu.com|119.75.218.45|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 8403 (8.2K) [text/html]
    Saving to: `index.html'

    100%[==========================================================================================>] 8,403       --.-K/s   in 0.01s  

    2011-10-17 16:30:10 (648 KB/s) - `index.html' saved [8403/8403]

    3.curl会显示出源码

    curl http://www.baidu.com/index.html

    4.lynx(这个以前在群里面见有人讨论过,但是没有尝试过,想用的话还需要下载软件)

    lynx http://www.baidu.com

     

    展开全文
  • linux环境下,手工模拟浏览器请求,手工拼装http请求 。使用nc命令 先安装nc,切换到root用户:yum install -y nc 安装成功后 先发起个请求nc www.baidu.com 80 -v 然后输入请求行 GET / HTTP/1.0 Host:...

    linux环境下,手工模拟浏览器请求,手工拼装http请求 。使用nc命令

    先安装nc,切换到root用户:yum install -y nc

    安装成功后

    先发起个请求nc www.baidu.com 80 -v

    然后输入请求行

    GET / HTTP/1.0

    Host:www.baidu.com

    最后远程服务器会给你返回许多东西

    展开全文
  • 目前的想法是,linux下有没有什么框架可以模拟浏览器,获得加载后的网页内容,再提取里面的url,或者截获加载过程中浏览器发出的http请求的url,这样应该可以确保抓取网页的完整性。另外,目前是linux下c++开发的,...
  • 当我们在浏览器的地址栏输入 www.linux178.com ,然后回车,回车这一瞬间到看到页面到底发生了什么呢? 整个流程如下: 域名解析 -->发起TCP的3次握手 -->建立TCP连接后发起http请求 -->服务器响应http请求,...

    当我们在浏览器的地址栏输入 www.linux178.com ,然后回车,回车这一瞬间到看到页面到底发生了什么呢?
    整个流程如下:

    • 域名解析 -->
    • 发起TCP的3次握手 -->
    • 建立TCP连接后发起http请求 -->
    • 服务器响应http请求,浏览器得到html代码 -->
    • 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) -->
    • 浏览器对页面进行渲染呈现给用户

    以下就是上面过程的一一分析,我们就以Chrome浏览器为例:

    域名解析

    首先Chrome浏览器会解析 www.linux178.com 这个域名对应的IP地址。怎么解析到对应的IP地址?
    Chrome浏览器会首先搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存)。
    如果浏览器自身缓存找不到则会查看系统的DNS缓存,如果找到且没有过期则停止搜索解析到此结束.
    而如果本机没有找到DNS缓存,则浏览器会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器发起域名解析请求(通过的是UDP协议向DNS的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址),运营商的DNS服务器首先查找自身的缓存,找到对应的条目,且没有过期,则解析成功。如果没有找到对应的条目,则有运营商的DNS代我们的浏览器发起迭代DNS解析请求,它首先是会找根域的DNS的IP地址(这个DNS服务器都内置13台根域的DNS的IP地址),找打根域的DNS地址,就会向其发起请求(请问www.linux178.com这个域名的IP地址是多少啊?),根域发现这是一个顶级域com域的一个域名,于是就告诉运营商的DNS我不知道这个域名的IP地址,但是我知道com域的IP地址,你去找它去,于是运营商的DNS就得到了com域的IP地址,又向com域的IP地址发起了请求(请问www.linux178.com这个域名的IP地址是多少?),com域这台服务器告诉运营商的DNS我不知道www.linux178.com这个域名的IP地址,但是我知道linux178.com这个域的DNS地址,你去找它去,于是运营商的DNS又向linux178.com这个域名的DNS地址(这个一般就是由域名注册商提供的,像万网,新网等)发起请求(请问www.linux178.com这个域名的IP地址是多少?),这个时候linux178.com域的DNS服务器一查,诶,果真在我这里,于是就把找到的结果发送给运营商的DNS服务器,这个时候运营商的DNS服务器就拿到了www.linux178.com这个域名对应的IP地址,并返回给Windows系统内核,内核又把结果返回给浏览器,终于浏览器拿到了www.linux178.com对应的IP地址,该进行一步的动作了。

    发起TCP的3次握手

    拿到域名对应的IP地址之后,User-Agent(一般是指浏览器)会以一个随机端口(1024< 端口 < 65535)向服务器的WEB程序(常用的有httpd,nginx等)80端口发起TCP的连接请求。这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序(本文就以Nginx为例),最终建立了TCP/IP的连接。

    为什么HTTP协议要基于TCP来实现?

    TCP是一个端到端的可靠的面向连接的协议,所以HTTP基于传输层TCP协议不用担心数据的传输的各种问题

    建立TCP连接后发起http请求

    进过TCP3次握手之后,浏览器发起了http的请求,使用的http的方法 GET 方法,请求的URL是 / ,协议是HTTP/1.0


    下面是第12号包的详细内容:

    3.png
    3.png

    以上的报文是HTTP请求报文。

    那么HTTP请求报文和响应报文会是什么格式呢?

    个HTTP请求报文由请求行(request line),请求头部(header),
    空行和请求数据4个部分组成
    ,下图给出了请求报文的一般格式。

    HTTP请求头
    HTTP请求头
    请求行

    请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。
    HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。这里介绍最常用的GET方法和POST方法。

    • GET:当客户端要从服务器中读取文档时,使用GET方法。GET方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。使用GET方法时,请求参数和对应的值附加在URL后面,利用一个问号(“?”)代表URL的结尾与请求参数的开始,传递参数长度受限制。例如,/index.jsp?id=100&op=bind。
    • POST:当客户端给服务器提供信息较多时可以使用POST方法。POST方法将请求参数封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据。
      请求头部
      请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
      User-Agent:产生请求的浏览器类型。
      Accept:客户端可识别的内容类型列表。
      Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
      空行
      最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
      请求数据
      请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。
    那么起始行中的请求方法有哪些种呢?

    GET: 完整请求一个资源 (常用)
    HEAD: 仅请求响应首部
    POST:提交表单 (常用)
    PUT: 上传
    DELETE:删除

    那什么是URL、URI、URN?

    URI Uniform Resource Identifier 统一资源标识符
    URL Uniform Resource Locator 统一资源定位符 格式如下: scheme://[username:password@]HOST:port/path/to/source http://www.magedu.com/downloads/nginx-1.5.tar.gzURN Uniform Resource Name 统一资源名称URL和URN 都属于 URI为了方便就把URL和URI暂时都通指一个东西

    请求的协议有哪些种?
    有以下几种:
    http/0.9: statelesshttp/1.0: MIME, keep-alive (保持连接), 缓存http/1.1: 更多的请求方法,更精细的缓存控制,持久连接(persistent connection) 比较常用

    下面是Chrome发起的http请求报文头部信息

    4.png
    4.png

    其中
    Accept 就是告诉服务器端,我接受那些MIME类型Accept-Encoding 这个看起来是接受那些压缩方式的文件Accept-Lanague 告诉服务器能够发送哪些语言 Connection 告诉服务器支持keep-alive特性Cookie 每次请求时都会携带上Cookie以方便服务器端识别是否是同一个客户端Host 用来标识请求服务器上的那个虚拟主机,比如Nginx里面可以定义很多个虚拟主机 那这里就是用来标识要访问那个虚拟主机。User-Agent 用户代理,一般情况是浏览器,也有其他类型,如:wget curl 搜索引擎的蜘蛛等 条件请求首部:If-Modified-Since 是浏览器向服务器端询问某个资源文件如果自从什么时间修改过,那么重新发给我,这样就保证服务器端资源 文件更新时,浏览器再次去请求,而不是使用缓存中的文件安全请求首部:Authorization: 客户端提供给服务器的认证信息;

    服务器端响应http请求,浏览器得到html代码

    服务器端WEB程序接收到http请求以后,就开始处理该请求,处理之后就返回给浏览器html文件。

    5.png
    5.png

    第32号包 是服务器返回给客户端http响应包(200 ok 响应的MIME类型是text/html),代表这一次客户端发起的http请求已成功响应。200 代表是的 响应成功的状态码,还有其他的状态码如下:
    1xx: 信息性状态码 100, 101
    2xx: 成功状态码 200:OK
    3xx: 重定向状态码
    301: 永久重定向, Location响应首部的值仍为当前URL,因此为隐藏重定向;
    302: 临时重定向,显式重定向, Location响应首部的值为新的URL
    304:Not Modified 未修改,比如本地缓存的资源文件和服务器上比较时,发现并没有修改,服务器返回一个304状态码, 告诉浏览器,你不用请求该资源,直接使用本地的资源即可。
    4xx: 客户端错误状态码
    404: Not Found 请求的URL资源并不存在
    5xx: 服务器端错误状态码
    500: Internal Server Error 服务器内部错误
    502: Bad Gateway 前面代理服务器联系不到后端的服务器时出现
    504:Gateway Timeout 这个是代理能联系到后端的服务器,但是后端的服务器在规定的时间内没有给代理服务器响应

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

    浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源。

    浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件。

    10.png
    10.png

    浏览器对页面进行渲染呈现给用户

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



    文/lintong(简书作者)
    原文链接:http://www.jianshu.com/p/fbe0e9fa45a6
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
    展开全文
  • 使用httpClient发送无参数get请求,代码如下 //创建一个httpClient对象 CloseableHttpClient httpClient=HttpClients.createDefault(); //创建一个Get对象 HttpGet get=new HttpGet("http://www.sogou.com"...
    1. 使用httpClient发送无参数get请求,代码如下
    		//创建一个httpClient对象
    		CloseableHttpClient httpClient=HttpClients.createDefault();
    		//创建一个Get对象
    		HttpGet get=new HttpGet("http://www.sogou.com");
    		//执行请求
    		CloseableHttpResponse response = httpClient.execute(get);
    		//取响应的结果
    		int statusCode = response.getStatusLine().getStatusCode();
    		System.out.println(statusCode);
    		HttpEntity entity = response.getEntity();
    		String string = EntityUtils.toString(entity,"utf-8");
    		System.out.println(string);
    		//关闭httpClient
    		response.close();
    		httpClient.close();
    
    1. 使用httpClient发送带参数的get请求,有两种方式
      第一种,在上述无参数的方法中,在创建get对象时,将参数附在url后面,例如:HttpGet get=new HttpGet(“http://www.sogou.com?query=“花千骨””);
      第二种方法,创建一个URL对象,将参数添加进URL对象中,再使用URL对象创建get对象,代码如下:
    		//创建一个httpclient对象
    		CloseableHttpClient httpClient=HttpClients.createDefault();
    		//创建一个url对象并添加参数
    		URIBuilder uriBuilder=new URIBuilder("https://www.sogou.com/sie");
    		uriBuilder.addParameter("query", "花千骨");
    		HttpGet get=new HttpGet(uriBuilder.build());
    		//执行请求,获得响应
    		CloseableHttpResponse response = httpClient.execute(get);
    		//取响应的结果
    		int statusCode = response.getStatusLine().getStatusCode();
    		System.out.println(statusCode);
    		HttpEntity entity = response.getEntity();
    		String string = EntityUtils.toString(entity,"utf-8");
    		System.out.println(string);
    		//关闭httpclient
    		response.close();
    		httpClient.close();
    
    1. 使用httpClient发送无参数的post请求,与无参数的get请求类似,区别只是不创建get对象,而是创建post对象,代码如下:
    CloseableHttpClient httpClient=HttpClients.createDefault();
    		//创建一个post对象
    		HttpPost post=new HttpPost("http://localhost:8082/httpclient/post.html");
    		CloseableHttpResponse response = httpClient.execute(post);
    		String string = EntityUtils.toString(response.getEntity());
    		System.out.println(string);
    		response.close();
    		httpClient.close();
    
    1. 使用httpClient发送有参数的post请求,比较复杂,需创建Entity对象,先模拟表单,创建一个基类是实现NameValuePair接口的list,然后将参数使用BasicNameValuePair类添加进list当中,在将此list封装成Entity对象,然后设置给post,代码如下:
    CloseableHttpClient httpClient=HttpClients.createDefault();
    		//创建一个post对象
    		HttpPost post=new HttpPost("http://localhost:8082/httpclient/post.html");
    		//创建一个Entity,模拟一个表单
    		List<NameValuePair> kvList=new ArrayList<>();
    		kvList.add(new BasicNameValuePair("name", "zhangsan"));
    		kvList.add(new BasicNameValuePair("password","123456"));
    		//包装成一个Entity对象
    		StringEntity entity=new UrlEncodedFormEntity(kvList);
    		//设置请求的内容
    		post.setEntity(entity);
    		CloseableHttpResponse response = httpClient.execute(post);
    		String string = EntityUtils.toString(response.getEntity());
    		System.out.println(string);
    		response.close();
    		httpClient.close();
    
    展开全文
  • WEB请求处理一:浏览器请求发起处理 最近,终于要把《WEB请求处理系列》提上日程了,一直答应小伙伴们给分享一套完整的WEB请求处理流程:从浏览器、Nginx、Servlet容器,最终到应用程序WEB请求的一个处理流程,前...


    http://my.oschina.net/xianggao/blog/669497


    0 系列目录

    最近,终于要把《WEB请求处理系列》提上日程了,一直答应小伙伴们给分享一套完整的WEB请求处理流程:从浏览器、Nginx、Servlet容器,最终到应用程序WEB请求的一个处理流程,前段时间由于其他工作事情的安排,一直未进行整理。不过还好该系列终于启动了,给大家分享的同时,也顺便整理下自己的思路,以便温故而知新吧。希望大家都能在此过程中得到新的收获吧。

    本系列主要分五部分:

    1.《WEB请求处理一:浏览器请求发起处理》:分析用户在浏览器中输入URL地址,浏览器如何找到服务器地址的过程,并发起请求;

    2.《WEB请求处理二:Nginx请求反向代理》:分析请求在达反向代理服务器内部处理过程;

    3.《WEB请求处理三:Servlet容器请求处理》:分析请求在Servlet容器内部处理过程,并找到目标应用程序;

    4.《WEB请求处理四:WEB MVC框架请求处理》:分析请求在应用程序内部,开源MVC框架的处理过程;

    5.《WEB请求处理五:浏览器请求响应处理》:分析请求在服务器端处理完成后,浏览器渲染响应页面过程;

    为直观明了,先上一张图,红色部分为本章所述模块:

    WEB请求处理流程

    1 B/S网络架构概述

    我们先了解下B/S网络架构是什么?B/S网络架构从前端到后端都得到了简化,都基于统一的应用层协议HTTP来交互数据,HTTP协议采用无状态的短链接的通信方式,通常情况下,一次请求就完成了一次数据交互,通常也对应一个业务逻辑,然后这次通信连接就断开了。采用这种方式是为了能够同时服务更多的用户,因为当前互联网应用每天都会处理上亿的用户请求,不可能每个用户访问一次后就一直保持住这个连接

    当一个用户在浏览器里输入www.google.com这个URL时,将会发生如下操作:

    1. 首先,浏览器会请求DNS把这个域名解析成对应的IP地址;

    2. 然后,根据这个IP地址在互联网上找到对应的服务器,建立Socket连接,向这个服务器发起一个HTTP Get请求,由这个服务器决定返回默认的数据资源给访问的用户;

    3. 在服务器端实际上还有复杂的业务逻辑:服务器可能有多台,到底指定哪台服务器处理请求,这需要一个负载均衡设备来平均分配所有用户的请求;

    4. 还有请求的数据是存储在分布式缓存里还是一个静态文件中,或是在数据库里;

    5. 当数据返回浏览器时,浏览器解析数据发现还有一些静态资源(如:css,js或者图片)时又会发起另外的HTTP请求,而这些请求可能会在CDN上,那么CDN服务器又会处理这个用户的请求;

    以上具体流程,如图所示:

    输入图片说明

    不管网络架构如何变化,但是始终有一些固定不变的原则需要遵守:

    1. 互联网上所有资源都要用一个URL来表示。URL就是统一资源定位符;

    2. 必须基于HTTP协议与服务端交互;

    3. 数据展示必须在浏览器中进行;

    2 HTTP协议解析

    B/S网络架构的核心是HTTP协议,最重要的就是要熟悉HTTP协议中的HTTP Header,HTTP Header控制着互联网上成千上万的用户的数据传输。最关键的是,它控制着用户浏览器的渲染行为和服务器的执行逻辑

    常见的HTTP请求头:

    输入图片说明

    常见的HTTP响应头:

    输入图片说明

    常见的HTTP状态码:

    输入图片说明

    2.1 浏览器缓存机制

    当我们使用Ctrl+F5组合键刷新一个页面时,首先是在浏览器端,会直接向目标URL发送请求,而不会使用浏览器缓存的数据;其次即使请求发送到服务端,也有可能访问到的是缓存的数据。所以在HTTP的请求头中会增加一些请求头,它告诉服务端我们要获取最新的数据而非缓存。最重要的是在请求Head中增加了两个请求项Pragma:no-cache和Cache-Control:no-cache

    1. Cache-Control/Pragma

      这个HTTP Head字段用于指定所有缓存机制在整个请求/响应链中必须服从的指令,如果知道该页面是否为缓存,不仅可以控制浏览器,还可以控制和HTTP协议相关的缓存或代理服务器

      Cache-Control/Pragma字段的可选值:

      输入图片说明

      Cache-Control请求字段被各个浏览器支持的较好,而且它的优先级也比较高,它和其他一些请求字段(如Expires)同时出现时,Cache-Control会覆盖其他字段

      Pragma字段的作用和Cache-Control有点类似,它也是在HTTP头中包含一个特殊的指令,使相关的服务器来遵守,最常用的就是Pragma:no-cache,它和Cache-Control:no-cache的作用是一样的

    2. Expires 缓存过期时间

      Expires通常的使用格式是Expires:Sat,25 Feb 2012 12:22:17 GMT,后面跟着一个日期和时间,超过这个值后,缓存的内容将失效,也就是浏览器在发出请求之前检查这个页面的这个字段,看该页面是否已经过期了,过期了将重新向服务器发起请求

    3. Last-Modified/Etag 最后修改时间

      Last-Modified字段一般用于表示一个服务器上的字段的最后修改时间,资源可以是静态(静态内容自动加上Last-Modified)或者动态的内容(如Servlet提供了一个getLastModified方法用于检查某个动态内容是否已经更新),通过这个最后修改时间可以判断当前请求的资源是否是最新的

      一般服务器端在响应头中返回一个Last-Modified字段,告诉浏览器这个页面的最后修改时间,如:Sat,25 Feb 2012 12:55:04 GMT,浏览器再次请求时在请求头中增加一个If-Modified-Since:Sat,25 Feb 2012 12:55:04 GMT字段,询问当前缓存的页面是否是最新的,如果是最新的就会返回304状态码,告诉浏览器是最新的,服务器也不会传输新的数据。

      与Last-Modified字段有类似功能的还有一个Etag字段,这个字段的作用是让服务端给每个页面分配一个唯一编号,然后通过这个编号来区分当前这个页面是否是最新的。这种方式比使用Last-Modified更加灵活,但是在后端的Web服务器有多台时比较难处理,因为每个Web服务器都要记住网站的所有资源编号,否则浏览器返回这个编号就没有意义了

    3 WEB工作流程

    对于正常的上网过程,系统其实是这样做的:

    浏览器本身是一个客户端,当你输入URL的时候,首先浏览器会去请求DNS服务器,通过DNS获取相应的域名对应的IP,然后通过IP地址找到IP对应的服务器后,要求建立TCP连接,等浏览器发送完HTTP Request(请求)包后,服务器接收到请求包之后才开始处理请求包,服务器调用自身服务,返回HTTP Response(响应)包;客户端收到来自服务器的响应后开始渲染这个Response包里的主体(body),等收到全部的内容随后断开与该服务器之间的TCP连接。

    输入图片说明

    Web服务器的工作原理可以简单地归纳为:

    1. 浏览器通过DNS域名解析到服务器IP;

    2. 客户机通过TCP/IP协议建立到服务器的TCP连接;

    3. 客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档;

    4. 服务器向客户机发送HTTP协议应答包,如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理“动态内容”,并将处理得到的数据返回给客户端;

    5. 客户机与服务器断开。由客户端解释HTML文档,在客户端屏幕上渲染图形结果;

    一个简单的HTTP事务就是这样实现的,看起来很复杂,原理其实是挺简单的。需要注意的是客户机与服务器之间的通信是非持久连接的,也就是当服务器发送了应答后就与客户机断开连接,等待下一次请求。

    4 DNS域名解析

    4.1 DNS域名解析过程

    当用户在浏览器中输入域名,如:www.google.com,并按下回车后,DNS解析过程大体如下:

    输入图片说明

    1. 浏览器缓存检查(本机)

      浏览器会首先搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存),看自身的缓存中是否有www.google.com对应的条目,而且没有过期,如果有且没有过期则解析到此结束

      浏览器缓存域名也是有限制的,不仅浏览器缓存大小有限制,而且缓存的时间也有限制,通常情况下为几分钟到几小时不等,域名被缓存的时间限制可以通过TTL属性来设置。这个缓存时间太长和太短都不好,如果缓存时间太长,一旦域名被解析到的IP有变化,会导致被客户端缓存的域名无法解析到变化后的IP地址,以致该域名不能正常解析,这段时间内有可能会有一部分用户无法访问网站。如果时间设置太短,会导致用户每次访问网站都要重新解析一次域名。

      注:我们怎么查看Chrome自身的缓存?可以使用 chrome://net-internals/#dns 来进行查看

      输入图片说明

    2. 操作系统缓存检查(本机)+hosts解析(本机)

      如果浏览器自身的缓存里面没有找到对应的条目,其实操作系统也会有一个域名解析的过程,那么Chrome会首先搜索操作系统自身的DNS缓存中是否有这个域名对应的DNS解析结果,如果找到且没有过期则停止搜索解析到此结束

      其次在Linux中可以通过/etc/hosts文件来设置,你可以将任何域名解析到任何能够访问的IP地址。如果你在这里指定了一个域名对应的IP地址,那么浏览器会首先使用这个IP地址。当解析到这个配置文件中的某个域名时,操作系统会在缓存中缓存这个解析结果,缓存的时间同样是受这个域名的失效时间和缓存的空间大小控制的。

    3. 本地区域名服务器解析(LDNS)

      如果在hosts文件中也没有找到对应的条目,浏览器就会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器(LDNS一般是电信运营商提供的,也可以使用像Google提供的DNS服务器)发起域名解析请求(通过的是UDP协议向DNS的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址)。

      在我们的网络配置中都会有“DNS服务器地址”这一项,这个地址就用于解决前面所说的如果两个过程无法解析时要怎么办,操作系统会把这个域名发送给这里设置的LDNS,也就是本地区的域名服务器这个DNS通常都提供给你本地互联网接入的一个DNS解析服务,例如你是在学校接入互联网,那么你的DNS服务器肯定在你的学校,如果你是在一个小区接入互联网的,那这个DNS就是提供给你接入互联网的应用提供商,即电信或者联通,也就是通常所说的SPA,那么这个DNS通常也会在你所在城市的某个角落,通常不会很远。这个专门的域名解析服务器性能都会很好,它们一般都会缓存域名解析结果,当然缓存时间是受域名的失效时间控制的,一般缓存空间不是影响域名失效的主要因素。大约80%的域名解析都到这里就已经完成了,所以LDNS主要承担了域名的解析工作。

      运营商的DNS服务器首先查找自身的缓存,找到对应的条目,且没有过期,则解析成功。

      输入图片说明

    4. 根域名服务器解析(Root Server)

      如果LDNS没有找到对应的条目,则由运营商的DNS代我们的浏览器发起迭代DNS解析请求。它首先是会找根域的DNS的IP地址(这个DNS服务器都内置13台根域的DNS的IP地址),找到根域的DNS地址,就会向其发起请求(请问www.google.com这个域名的IP地址是多少啊?)。

    5. 根域名服务器返回给本地域名服务器一个所查询域的主域名服务器(gTLD Server)地址,gTLD是国际顶级域名服务器,如.com、.cn、.org等,全球只有13台左右。

      根域发现这是一个顶级域com域的一个域名,于是就告诉运营商的DNS我不知道这个域名的IP地址,但是我知道com域的IP地址,你去找它去。

    6. 本地域名服务器(Local DNS Server)再向上一步返回的gTLD服务器发送请求

      于是运营商的DNS就得到了com域的IP地址,又向com域的IP地址发起了请求(请问www.google.com这个域名的IP地址是多少?),com域这台服务器告诉运营商的DNS我不知道www.google.com这个域名的IP地址,但是我知道google.com这个域的DNS地址,你去找它去。

    7. 接受请求的gTLD服务器查找并返回此域名对应的Name Server域名服务器的地址,这个Name Server通常就是你注册的域名服务器,例如你在某个域名服务提供商申请的域名,那么这个域名解析任务就由这个域名提供商的服务器来完成。

      于是运营商的DNS又向google.com这个域名的DNS地址(这个一般就是由域名注册商提供的,像万网,新网等)发起请求(请问www.google.com这个域名的IP地址是多少?),这个时候google.com域的DNS服务器一查,果真在我这里,于是就把找到的结果发送给运营商的DNS服务器,这个时候运营商的DNS服务器就拿到了www.google.com这个域名对应的IP地址

    8. Name Server域名服务器会查询存储的域名和IP的映射关系表,正常情况下都根据域名得到目标IP记录,连同一个TTL值返回给DNS Server域名服务器。

    9. 返回该域名对应的IP和TTL值,Local DNS Server会缓存这个域名和IP的对应关系,缓存的时间由TTL值控制。

    10. 把解析的结果返回给用户,用户根据TTL值缓存在本地系统缓存中,域名解析过程结束

    通过上面的步骤,我们最后获取的是IP地址,也就是浏览器最后发起请求的时候是基于IP来和服务器做信息交互的。在实际的DNS解析过程中,可能还不止这10个步骤,如Name Server也可能有多级,或者有一个GTM来负载均衡控制,这都有可能会影响域名解析的过程。根据以上解析流程,DNS解析整个过程,分为:递归查询过程和迭代查询过程。如图所示:

    输入图片说明

    所谓 递归查询过程 就是 “查询的递交者” 更替, 而 迭代查询过程 则是 “查询的递交者”不变。

    举个例子来说,你想知道某个一起上法律课的女孩的电话,并且你偷偷拍了她的照片,回到寝室告诉一个很仗义的哥们儿,这个哥们儿二话没说,拍着胸脯告诉你,甭急,我替你查(此处完成了一次递归查询,即,问询者的角色更替)。然后他拿着照片问了学院大四学长,学长告诉他,这姑娘是xx系的;然后这哥们儿马不停蹄又问了xx系的办公室主任助理同学,助理同学说是xx系yy班的,然后很仗义的哥们儿去xx系yy班的班长那里取到了该女孩儿电话。(此处完成若干次迭代查询,即,问询者角色不变,但反复更替问询对象)最后,他把号码交到了你手里。完成整个查询过程。

    4.2 跟踪域名解析过程

    在Linux系统中还可以使用dig命名来查询DNS的解析过程,如下所示:dig +cmd +trace www.google.com

    输入图片说明

    上面清楚地显示了整个域名是如何发起和解析的,从根域名(.)到gTLD Server(.com.)再到Name Server (google.com.)的整个过程都显示出来了。还可以看出DNS的服务器有多个备份,可以从任何一台查询到解析结果。

    4.3 清除缓存的域名

    我们知道DNS域名解析后会缓存解析结果,其中主要在两个地方缓存结果,一个是Local DNS Server,另外一个是用户的本地机器。这两个缓存都是TTL值和本机缓存大小控制的,但是最大缓存时间是TTL值,基本上Local DNS Server的缓存时间就是TTL控制的,很难人工介入,但是我们的本机缓存可以通过如下方式清除。

    在Linux下可以通过/etc/init.d/nscd restart来清除缓存。如下:

    输入图片说明

    JVM缓存DNS解析结果:在Java应用中JVM也会缓存DNS的解析结果,这个缓存是在InetAddress类中完成的,而且这个缓存时间还比较特殊,它有两种缓存策略:一种是正确解析结果缓存,另一种是失败的解析结果缓存。这两个缓存时间由两个配置项控制,配置项是在%JAVA_ HOME%\lib\security\java.security文件中配置的。两个配置项分别是networkaddress.cache.ttl 和networkaddress.cache.negative.ttl,它们的默认值分别是-1(永不失效)和10(缓存10秒)。

    要修改这两个值同样有几种方式,分别是:直接修改java.security文件中的默认值、在Java的启动参数中增加-Dsun.net.inetaddr.ttl=xxx来修改默认值、通过InetAddress类动态修改。

    在这里还要特别强调一下,如果我们需要用InetAddress类解析域名时,一定要是单例模式,不然会有严重的性能问题,如果每次都创建InetAddress实例,每次都要进行一次完整的域名解析,非常耗时,这点要特别注意。

    4.4 几种域名解析方式

    1. A记录,A代表的是Address,用来指定域名对应的IP地址

      如将item.taobao.com指定到115.238.23.241,将switch.taobao.com指定到121.14.24.241。A记录可以将多个域名解析到一个IP地址,但是不能将一个域名解析到多个IP地址

    2. MX记录,表示的是Mail Exchange,就是可以将某个域名下的邮件服务器指向自己的Mail Server

      如taobao.com域名的A记录IP地址是115.238.25.245,如果MX记录设置为115.238.25.246,是xxx@taobao.com的邮件路由,DNS会将邮件发送到115.238.25.246所在的服务器,而正常通过Web请求的话仍然解析到A记录的IP地址

    3. CNAME记录,全称是Canonical Name(别名解析),所谓的别名解析就是可以为一个域名设置一个或者多个别名

      如将taobao.com解析到xulingbo.net,将srcfan.com也解析到xulingbo.net,其中xulingbo.net分别是taobao.com和srcfan.com的别名。前面的跟踪域名解析中的“www.taobao.com. 1542 IN CNAME www.gslb.taobao.com”就是CNAME解析。

    4. NS记录,为某个域名指定DNS解析服务器,也就是这个域名有指定的IP地址的DNS服务器去解析

      前面的“google.com. 172800 IN NS ns4.google.com.”就是NS解析。

    5. TXT记录,为某个主机名或域名设置说明

      如可以为google.com设置TXT记录为“谷歌|中国”这样的说明。

    4.5 网络抓包分析

    Linux虚拟机测试,使用命令 wget www.linux178.com 来请求,发现直接使用chrome浏览器请求时,干扰请求比较多,所以就使用wget命令来请求,不过使用wget命令只能把index.html请求回来,并不会对index.html中包含的静态资源(js、css等文件)进行请求

    抓包截图如下:

    输入图片说明

    1号包,这个是那台虚拟机在广播,要获取192.168.100.254(也就是网关)的MAC地址,因为局域网的通信靠的是MAC地址,它为什么需要跟网关进行通信是因为我们的DNS服务器IP是外围IP,要出去必须要依靠网关帮我们出去才行

    2号包,这个是网关收到了虚拟机的广播之后,回应给虚拟机的回应,告诉虚拟机自己的MAC地址,于是客户端找到了路由出口。

    3号包,这个包是wget命令向系统配置的DNS服务器提出域名解析请求(准确的说应该是wget发起了一个DNS解析的系统调用),请求的域名www.linux178.com,期望得到的是IP6的地址(AAAA代表的是IPv6地址)

    4号包,这个DNS服务器给系统的响应,很显然目前使用IPv6的还是极少数,所以得不到AAAA记录的。

    5&6号包,这个还是请求解析IPv6地址,但是www.linux178.com.leo.com这个主机名是不存在的,所以得到结果就是no such name。

    7号包,这个才是请求的域名对应的IPv4地址(A记录)。

    8号包,DNS服务器不管是从缓存里面,还是进行迭代查询最终得到了域名的IP地址,响应给了系统,系统再给了wget命令,wget于是得到了www.linux178.com的IP地址,这里也可以看出客户端和本地的DNS服务器是递归的查询(也就是服务器必须给客户端一个结果)这就可以开始下一步了,进行TCP的三次握手。

    5 发起TCP的3次握手

    拿到域名对应的IP地址之后,User-Agent(一般是指浏览器)会以一个随机端口(1024 < 端口 < 65535)向服务器的WEB程序(常用的有httpd,nginx等)80端口发起TCP的连接请求。这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。

    如下图所示:

    输入图片说明

    1. Client首先发送一个连接试探,ACK=0 表示确认号无效,SYN = 1 表示这是一个连接请求或连接接受报文,同时表示这个数据报不能携带数据,seq = x 表示Client自己的初始序号(seq = 0 就代表这是第0号包),这时候Client进入syn_sent状态,表示客户端等待服务器的回复。

    2. Server监听到连接请求报文后,如同意建立连接,则向Client发送确认。TCP报文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到对方下一个报文段的第一个数据字节序号是x+1,同时表明x为止的所有数据都已正确收到(ack=1其实是ack=0+1,也就是期望客户端的第1个包),seq = y 表示Server自己的初始序号(seq=0就代表这是服务器这边发出的第0号包)。这时服务器进入syn_rcvd,表示服务器已经收到Client的连接请求,等待client的确认。

    3. Client收到确认后还需再次发送确认,同时携带要发送给Server的数据。ACK 置1 表示确认号ack= y + 1 有效(代表期望收到服务器的第1个包),Client自己的序号seq= x + 1(表示这就是我的第1个包,相对于第0个包来说的),一旦收到Client的确认之后,这个TCP连接就进入Established状态,就可以发起http请求了。

    看抓包截图:

    输入图片说明

    TCP 为什么需要3次握手?

    举个例子:假设一个老外在故宫里面迷路了,看到了小明,于是就有下面的对话:

    老外: Excuse me,Can you Speak English?

    小明: yes 。

    老外: OK,I want ...

    在问路之前,老外先问小明是否会说英语,小明回答是的,这时老外才开始问路。

    2个计算机通信是靠协议(目前流行的TCP/IP协议)来实现,如果2个计算机使用的协议不一样,那是不能进行通信的,所以这个3次握手就相当于试探一下对方是否遵循TCP/IP协议,协商完成后就可以进行通信了,当然这样理解不是那么准确。

    为什么HTTP协议要基于TCP来实现?

    目前在Internet中所有的传输都是通过TCP/IP进行的,HTTP协议作为TCP/IP模型中应用层的协议也不例外,TCP是一个端到端的可靠的面向连接的协议,所以HTTP基于传输层TCP协议不用担心数据的传输的各种问题。

    6 建立TCP连接后发起http请求

    经过TCP3次握手之后,浏览器发起了http的请求(看第⑫包),使用的http的方法 GET 方法,请求的URL是 / ,协议是HTTP/1.0:

    输入图片说明

    下面是第12号包的详细内容:

    输入图片说明

    以上的报文是HTTP请求报文。那么HTTP请求报文和响应报文会是什么格式呢?

    起始行:如 GET / HTTP/1.0 (请求的方法 请求的URL 请求所使用的协议)

    头部信息:User-Agent Host等成对出现的值

    主体

    不管是请求报文还是响应报文都会遵循以上的格式。那么起始行中的请求方法有哪些种呢?

    GET: 完整请求一个资源 (常用)

    HEAD: 仅请求响应首部

    POST: 提交表单 (常用)

    PUT: 上传

    DELETE: 删除

    OPTIONS: 返回请求的资源所支持的方法的方法

    TRACE: 追求一个资源请求中间所经过的代理

    那什么是URL、URI、URN?

    URI Uniform Resource Identifier 统一资源标识符,如:scheme://[username:password@]HOST:port/path/to/source

    URL Uniform Resource Locator 统一资源定位符,如:http://www.magedu.com/downloads/nginx-1.5.tar.gz

    URN Uniform Resource Name 统一资源名称

    URL和URN都属于URI,为了方便就把URL和URI暂时都通指一个东西。

    请求的协议有哪些种?有以下几种:

    http/0.9: stateless

    http/1.0: MIME, keep-alive (保持连接), 缓存

    http/1.1: 更多的请求方法,更精细的缓存控制,持久连接(persistent connection) 比较常用

    下面是Chrome发起的http请求报文头部信息:

    输入图片说明

    Accept 就是告诉服务器端,接受那些MIME类型

    Accept-Encoding 这个看起来是接受那些压缩方式的文件

    Accept-Lanague 告诉服务器能够发送哪些语言

    Connection 告诉服务器支持keep-alive特性,TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的TCP连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

    Cookie 每次请求时都会携带上Cookie以方便服务器端识别是否是同一个客户端

    Host 用来标识请求服务器上的那个虚拟主机,比如Nginx里面可以定义很多个虚拟主机,那这里就是用来标识要访问那个虚拟主机。

    User-Agent 用户代理,一般情况是浏览器,也有其他类型,如:wget curl 搜索引擎的蜘蛛等

    条件请求头部:If-Modified-Since是浏览器向服务器端询问某个资源文件如果自从什么时间修改过,那么重新发给我,这样就保证服务器端资源文件更新时,浏览器再次去请求,而不是使用缓存中的文件。

    安全请求头部:Authorization: 客户端提供给服务器的认证信息;

    什么是MIME?

    MIME(Multipurpose Internet Mail Extesions 多用途互联网邮件扩展)是一个互联网标准,它扩展了电子邮件标准,使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息,这个标准被定义在RFC 2045、RFC 2046、RFC 2047、RFC 2048、RFC 2049等RFC中。 由RFC 822转变而来的RFC 2822,规定电子邮件标准并不允许在邮件消息中使用7位ASCII字符集以外的字符。正因如此,一些非英语字符消息和二进制文件,图像,声音等非文字消息都不能在电子邮件中传输。

    MIME规定了用于表示各种各样的数据类型的符号化方法。此外,在万维网中使用的HTTP协议中也使用了MIME的框架,标准被扩展为互联网媒体类型

    MIME 遵循以下格式:major/minor 主类型/次类型 例如:

    image/jpg

    image/gif

    text/html

    video/quicktime

    appliation/x-httpd-php

    赞赏我的文章给您带来收获

    输入图片说明


    展开全文
  • 如果急需使用的话,直接用目录调到后面即可...它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核等信息标识。通过这个标识,用户所访问的网站可以显示不同的排版...
  • 最近一直在学习linux网络编程这一块的内容,自己做了一个简单web服务器,以前无法确切的了解web浏览器访问网页的的请求过程。现在有着样的条件了,所以就自己实现一下看看过程了。 浏览器展示一个网页的过程:...
  • 随着信息技术与网络技术的快速发展,以及人们日常生活对网络信息的需求的不断增加。...而且Linux操作系统完全开源,可以降低产品开发成本,因此对基于Linux操作系统的嵌入式浏览器开发技术的研究有着重要意义。
  • User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等...一:获得浏览器请求头中的User-Agen
  • 完全没装图形模式的linux,用模拟浏览器是不可能的,但是有个折中的办法就是装xvfb ubuntu下面: sudo apt-get install xdg-utils xvfb x11-xkb-utils 然后在python里面要装个包:xvfbwrapper python3 -m pip ...
  • user_agent = [ "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", "Mozilla/5.0 (Windows; U; Windows NT 6.1;...
  • 客户端向服务器发送一个请求请求头包含请求的方法、URI、协议版本、以及包含请求修饰符、客户信息和内容的类似于MIME的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码...
  • user_agent = [ “Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50”, “Mozilla/5.0 (Windows; U; Windows NT 6.1;...
  • ...
  •  它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。通过这个标识,用户所访问的网站可以显示不同的排版从而为用户提供更好的体验或者进行信息...
  • http://blog.jobbole.com/100461/
  • 有的网站只允许浏览器访问,如果在Linux上直接访问而不设置user-agent是会被哔掉的~~ 以下为wget和curl命令模拟浏览器下载和访问. wget--user-agent="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36...
  • 设备:Google Nexus 5X ...浏览器 UA UC Mozilla/5.0 (Linux; U; Android 7.0; zh-CN; Nexus 5X Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11....
1 2 3 4 5 ... 20
收藏数 120,621
精华内容 48,248
关键字:

linux 浏览器请求