2012-12-09 17:01:21 rentiansheng 阅读数 2113
  • Linux系列之走进Linux新世界

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    20476 人正在学习 去看看 马永亮


最近一直在学习linux网络编程这一块的内容,自己做了一个简单web服务器,以前无法确切的了解web浏览器访问网页的的请求过程。现在有着样的条件了,所以就自己实现一下看看过程了。

浏览器展示一个网页的过程:(不涉及本地缓存,假设本地没有缓存)

  1. 浏览器向服务发送请求,请求一个页面。

  2. 服务器响应请求,向浏览器发送页面。

  3. 浏览器加载页面,如果有外部文件,转向4步,没有结束

  4. 浏览器依次生成进程,分别请求所需文件。

  5. 服务器响应请求,向浏览器发送外部文件。

  6. 浏览器加载外部文件。

下面是我测试得到的结果的截图。(此网页中有外部的css、js、图片)

浏览器结果(本代码和结论只经过本人的简单测试,可能存在问题。请相信自己的能力,敢于质疑。欢迎提供更好的、更快、更简洁的代码或者方法和指出错误。在ubuntu12.04使用gcc4.6.3版本编译,在vc中如出现错误,请谅解。)

请求网页的效果图:



得到浏览器请求的结果:

 


看完测试结果后,大家发现浏览器先请求了页面,依次请求了外部文件所需要的文件。由于我写的是单线程的服务端,大家可能会看到浏览器发送请求的文件的顺序,如果你看了网页的源代码,你会发现web浏览器请求的顺序正好是网页中的书写顺序。我可以将想要优先显示的内容书写到代码考前的部位。

通过以上信息对于web开发者的建议:

  1. 将内容少的jscss直接嵌入网页中,从而减少浏览器的对web服务器的请求次数。减少web服务器的负担。

  2. 减少外部文件,将可以合并的文件放到一个文件中,从而减少浏览器的对web服务器的请求次数。减少web服务器的负担。(可以选择在发布时合并文件,便于开发。通常是css和js文件)

  3. 见多个小图表合并到一起,统一请求文件。
  4. 将优先显示的外部文件代码书写到前面。将不重要的文件放到最好请求。

  5. 同一个外部文件网页只会请求一次。

如果针对本页面来说,js为空,css内容也很少,如果直接嵌入网页页面中,将会只有两次web浏览器请求的。

代码和测试主页、makefile等文件:测试文件按文件地址

blog:http://blog.csdn.net/rentiansheng/article/details/8274489




2019-12-07 19:10:33 weixin_40816738 阅读数 7
  • Linux系列之走进Linux新世界

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    20476 人正在学习 去看看 马永亮

第一种:
在浏览器访问:

http://192.168.205.130:9000

另外一种是命令行形式

curl 192.168.205.130:9000

效果是一样的

2016-08-11 21:38:03 qq_30325409 阅读数 697
  • Linux系列之走进Linux新世界

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    20476 人正在学习 去看看 马永亮

当我们在浏览器的地址栏输入 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
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
2017-06-21 16:19:22 chrise_ 阅读数 1496
  • Linux系列之走进Linux新世界

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    20476 人正在学习 去看看 马永亮

这是因为Apache问题的原因,当时也是百思不得其解

我发现在Linux下就行,浏览器上就不行

后来仔细观察是因为Linux下会自动转换为POST的请求发出去

于是我们可以在web.xml下加入一个过滤器

配置如下:


<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Accept,Accept-Encoding,Accept-Language,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,Connection,Content-Type,Host,Origin,Referer,Token-Id,User-Agent, X-Requested-With</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET, POST, PUT, DELETE, OPTIONS, HEAD</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

这个时候你就会发现什么都好使了....

2019-03-27 22:21:52 lanyue1 阅读数 132
  • Linux系列之走进Linux新世界

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    20476 人正在学习 去看看 马永亮

现象:项目中使用angularjs2+cytoscape.js绘制网络拓扑图,其中节点背景使用了图片显示,在windows环境下调测,所有浏览器都正常显示,但是一放到Linux环境服务器上,IE11浏览器下访问无法显示,其他浏览器正常。

问题:通过对cytoscape.js源码打印发现请求图片是通过<img crossorigin="anonymous" src="assets/imgs/bird.jpg">方式去获取图片,打开nginx访问日志记录,只要IE11浏览器发送的http图片请求都会报302状态码。经分析,crossorigin属性是为了解决跨域问题使用,而我们项目中的图片都是在相应服务器上,并不需要跨域获取。

方法:将cytoscape.cjs.js中BRp.getCachedImage方法中如下内容

 var dataUriPrefix = 'data:';
    var isDataUri = url.substring(0, dataUriPrefix.length).toLowerCase() === dataUriPrefix;
    if (!isDataUri) {
      image.crossOrigin = crossOrigin; // prevent tainted canvas
    }

修改为:

if(url.indexOf("http://")!== -1||url.indexOf("https://")!== -1){
        image.crossOrigin = crossOrigin; // prevent tainted canvas
    }

 

 

HTTP请求

阅读数 528

没有更多推荐了,返回首页