概述
1、HTTP协议简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
2、HTTP工作原理
HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。
Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80,但是你也可以改为8080或者其他端口。
HTTP三点注意事项:
- HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定合适的MIME-type内容类型。
- HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对事物处理没有记忆能力。缺少状态意味着如何后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
下图展示了HTTP协议通信流程:
3、HTTP消息结构
HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
一个HTTP"客户端"是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。
一个HTTP"服务器"同样也是一个应用程序(通常是一个Web服务,如Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送HTTP响应数据。
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
一旦建立连接后,数据消息就通过类似Internet邮件所使用的格式[RFC5322]和多用途Internet邮件扩展(MIME)[RFC2045]来传送。
3.1、客户端请求消息
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
浏览器访问http://www.runoob.com/http/http-tutorial.html请求消息内容:
GET http://www.runoob.com/http/http-tutorial.html HTTP/1.1
Host: www.runoob.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://www.runoob.com/http/http-tutorial.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: __uid=22ebaa94c4c85d5bb897eec286316430; Hm_lvt_8e2a116daf0104a78d601f40a45c75b4=1531712410,1531712907,1531731129,1531875825; _gat_gtag_UA_84264393_2=1; SERVERID=3a4d90ce271dac423615bd00bfd9dc97|1538454183|1538454173; Hm_lvt_3eec0b7da6548cf07db3bc477ea905ee=1538403919,1538443038,1538446304,1538446308; Hm_lpvt_3eec0b7da6548cf07db3bc477ea905ee=1538454191; _ga=GA1.2.1982042162.1531825555; _gid=GA1.2.1749171910.1538324309
3.1.1、请求行
GET http://www.runoob.com/http/http-tutorial.html HTTP/1.1
解析:
请求方法:GET
URL:http://www.runoob.com/http/http-tutorial.html
协议版本:HTTP/1.1
3.1.2、请求头部
Host: www.runoob.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://www.runoob.com/http/http-tutorial.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: __uid=22ebaa94c4c85d5bb897eec286316430; Hm_lvt_8e2a116daf0104a78d601f40a45c75b4=1531712410,1531712907,1531731129,1531875825; _gat_gtag_UA_84264393_2=1; SERVERID=3a4d90ce271dac423615bd00bfd9dc97|1538454183|1538454173; Hm_lvt_3eec0b7da6548cf07db3bc477ea905ee=1538403919,1538443038,1538446304,1538446308; Hm_lpvt_3eec0b7da6548cf07db3bc477ea905ee=1538454191; _ga=GA1.2.1982042162.1531825555; _gid=GA1.2.1749171910.1538324309
Fiddler软件解析:
3.1.3、请求数据
请求数据为空。
3.2、服务器响应消息
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
浏览器访问http://www.runoob.com/http/http-tutorial.html,服务器响应内容:
HTTP/1.1 200 OK
Server: Tengine
Content-Type: text/html
Content-Length: 46318
Connection: keep-alive
Date: Mon, 01 Oct 2018 07:22:39 GMT
X-Powered-By: HHVM/3.28.1
Vary: Accept-Encoding
Via: cache43.l2st3-1[0,200-0,H], cache25.l2st3-1[2,0], kunlun7.cn257[0,200-0,H], kunlun6.cn257[0,0]
Age: 75638
Ali-Swift-Global-Savetime: 1538446306
X-Cache: HIT TCP_MEM_HIT dirn:1:11089010
X-Swift-SaveTime: Tue, 02 Oct 2018 02:11:46 GMT
X-Swift-CacheTime: 86400
Timing-Allow-Origin: *
EagleId: de551ac615384541979717849e
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta property="qc:admins" content="465267610762567726375" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTTP 教程 | 菜鸟教程</title>
<link rel=‘dns-prefetch‘ href=‘//s.w.org‘ />
<link rel="canonical" href="http://www.runoob.com/http/http-tutorial.html" />
<meta name="keywords" content="HTTP 教程,HTTP">
<meta name="description" content="HTTP 教程 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。 HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。 内容列表 HTTP 简介 本章节介绍了HTTP协议。 HTTP 消息结构 本章节介绍了HTTP消息结构 HTTP 方法 本章节介绍了HTTP的方法,包括..">
<link rel="shortcut icon" href="//static.runoob.com/images/favicon.ico" mce_href="//static.runoob.com/images/favicon.ico" type="image/x-icon" >
<link rel="stylesheet" href="/wp-content/themes/runoob/style.css?v=1.147" type="text/css" media="all" />
<link rel="stylesheet" href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" media="all" />
<!--[if gte IE 9]><!-->
<script src="//cdn.bootcss.com/jquery/2.0.3/jquery.min.js"></script>
<!--<![endif]-->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/html5shiv/r29/html5.min.js"></script>
<![endif]-->
<link rel="apple-touch-icon" href="//static.runoob.com/images/icon/mobile-icon.png"/>
<meta name="apple-mobile-web-app-title" content="菜鸟教程">
</head>
<body>
<!-- 头部 -->
<div class="container logo-search">
<div class="col search row-search-mobile">
<form action="index.php">
<input class="placeholder" placeholder="搜索……" name="s" autocomplete="off">
</form>
</div>
<div class="row">
<div class="col logo">
<h1><a href="/">菜鸟教程 -- 学的不仅是技术,更是梦想!</a></h1>
</div>
<div class="col right-list">
<button class="btn btn-responsive-nav btn-inverse" data-toggle="collapse" data-target=".nav-main-collapse" id="pull" style=""> <i class="fa fa-navicon"></i> </button>
</div>
<div class="col search search-desktop last">
<form action="//www.runoob.com/" target="_blank">
<input class="placeholder" id="s" name="s" placeholder="搜索……" autocomplete="off">
</form>
</div>
</div>
</div>
<!-- 导航栏 -->
<!-- 导航栏 -->
<div class="container navigation">
<div class="row">
<div class="col nav">
<ul class="pc-nav">
<li><a href="//www.runoob.com/">首页</a></li>
<li><a href="/html/html-tutorial.html">HTML</a></li>
<li><a href="/css/css-tutorial.html">CSS</a></li>
<li><a href="/js/js-tutorial.html">JavaScript</a></li>
<li><a href="/jquery/jquery-tutorial.html">jQuery</a></li>
<li><a href="/bootstrap/bootstrap-tutorial.html">Bootstrap</a></li>
<li><a href="/sql/sql-tutorial.html">SQL</a></li>
<li><a href="/mysql/mysql-tutorial.html">MySQL</a></li>
<li><a href="/php/php-tutorial.html">PHP</a></li>
<li><a href="/python/python-tutorial.html">Python2</a></li>
<li><a href="/python3/python3-tutorial.html">Python3</a></li>
<li><a href="/cprogramming/c-tutorial.html">C</a></li>
<li><a href="/cplusplus/cpp-tutorial.html">C++</a></li>
<li><a href="/csharp/csharp-tutorial.html">C#</a></li>
<li><a href="/java/java-tutorial.html">Java</a></li>
<li><a href="/browser-history">本地书签</a></li>
<!--
<li><a href="javascript:;" class="runoob-pop">登录</a></li>
-->
</ul>
<ul class="mobile-nav">
<li><a href="//www.runoob.com/">首页</a></li>
<li><a href="/html/html-tutorial.html">HTML</a></li>
<li><a href="/css/css-tutorial.html">CSS</a></li>
<li><a href="/js/js-tutorial.html">JS</a></li>
<li><a href="/browser-history">本地书签</a></li>
<a href="javascript:void(0)" class="search-reveal">Search</a>
</ul>
</div>
</div>
</div><!-- 内容 -->
<div class="container main">
<!-- 中间 -->
<div class="row">
<div class="col left-column">
<div class="tab">HTTP 教程 <a data-cate="50" href="javascript:void(0);" title="夜间模式" id="moon"><i class="fa fa-moon-o" aria-hidden="true" style="font-size: 1.4em;float: right;margin: 4px 6px 0;"></i></a>
<a data-cate="50" style="display:none;" href="javascript:void(0);" title="日间模式" id="sun" ><i class="fa fa-sun-o" aria-hidden="true" style="font-size: 1.4em;float: right;margin: 4px 6px 0;"></i></a>
</div>
<div class="sidebar-box gallery-list">
<div class="design" id="leftcolumn">
<a target="_top" title="HTTP 教程" href="/http/http-tutorial.html" >
HTTP 教程 </a>
<a target="_top" title="HTTP 简介" href="/http/http-intro.html" >
HTTP 简介 </a>
<a target="_top" title="HTTP 消息结构" href="/http/http-messages.html" >
HTTP 消息结构 </a>
<a target="_top" title="HTTP请求方法" href="/http/http-methods.html" >
HTTP请求方法 </a>
<a target="_top" title="HTTP 响应头信息" href="/http/http-header-fields.html" >
HTTP 响应头信息 </a>
<a target="_top" title="HTTP状态码" href="/http/http-status-codes.html" >
HTTP状态码 </a>
<a target="_top" title="HTTP content-type" href="/http/http-content-type.html" >
HTTP content-type </a>
</div>
</div>
</div> <div class="col middle-column">
<div class="article">
<div class="article-heading-ad" style="display: none;">
</div>
<div class="previous-next-links">
<div class="previous-design-link"><i style="font-size:16px;" class="fa fa-arrow-left" aria-hidden="true"></i> <a href="http://www.runoob.com/http/http-status-codes.html" rel="prev"> HTTP状态码</a> </div>
<div class="next-design-link"><a href="http://www.runoob.com/http/http-content-type.html" rel="next"> HTTP content-type</a> <i style="font-size:16px;" class="fa fa-arrow-right" aria-hidden="true"></i></div>
</div>
<div class="article-body">
<div class="article-intro" id="content">
<h1>HTTP 教程</h1><hr>
<div class="tutintro">
<p>HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。</p>
<p>HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。</p>
</div>
<hr>
<h3><span style="text-decoration: underline;">内容列表</span></h3>
<p><a href="/http/http-intro.html">HTTP 简介</a><br>
本章节介绍了HTTP协议。</p>
<p><a href="/http/http-messages.html">HTTP 消息结构</a><br>
本章节介绍了HTTP消息结构</p>
<p><a href="/http/http-methods.html">HTTP 方法</a><br>
本章节介绍了HTTP的方法,包括 GET, POST, HEAD 等。</p>
<p><a href="/http/http-header-fields.html">HTTP 头信息</a><br>
本章节介绍了HTTP的头信息</p>
<p><a href="/http/http-status-codes.html">HTTP 状态码</a><br>
本章节列出了所有HTTP的状态码。</p>
</div>
</div>
<div class="previous-next-links">
<div class="previous-design-link"><i style="font-size:16px;" class="fa fa-arrow-left" aria-hidden="true"></i> <a href="http://www.runoob.com/http/http-status-codes.html" rel="prev"> HTTP状态码</a> </div>
<div class="next-design-link"><a href="http://www.runoob.com/http/http-content-type.html" rel="next"> HTTP content-type</a> <i style="font-size:16px;" class="fa fa-arrow-right" aria-hidden="true"></i></div>
</div>
<!-- 笔记列表 -->
<style>
.wrapper {
/*text-transform: uppercase; */
background: #ececec;
color: #555;
cursor: help;
font-family: "Gill Sans", Impact, sans-serif;
font-size: 20px;
position: relative;
text-align: center;
width: 200px;
-webkit-transform: translateZ(0); /* webkit flicker fix */
-webkit-font-smoothing: antialiased; /* webkit text rendering fix */
}
.wrapper .tooltip {
white-space: nowrap;
font-size: 14px;
text-align: left;
background: #96b97d;
bottom: 100%;
color: #fff;
display: block;
left: -25px;
margin-bottom: 15px;
opacity: 0;
padding: 14px;
pointer-events: none;
position: absolute;
-webkit-transform: translateY(10px);
-moz-transform: translateY(10px);
-ms-transform: translateY(10px);
-o-transform: translateY(10px);
transform: translateY(10px);
-webkit-transition: all .25s ease-out;
-moz-transition: all .25s ease-out;
-ms-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
-webkit-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
-moz-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
-ms-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
-o-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
}
.tooltip a {
color:#fff;
}
/* This bridges the gap so you can mouse into the tooltip without it disappearing */
.wrapper .tooltip:before {
bottom: -20px;
content: " ";
display: block;
height: 20px;
left: 0;
position: absolute;
width: 100%;
}
/* CSS Triangles - see Trevor‘s post */
.wrapper .tooltip:after {
border-left: solid transparent 10px;
border-right: solid transparent 10px;
border-top: solid #96b97d 10px;
bottom: -10px;
content: " ";
height: 0;
left: 20%;
margin-left: -13px;
position: absolute;
width: 0;
}
.wrapper .tooltip1 {
margin-left: 50px;
padding-top: 0px;
}
.wrapper:hover .tooltip {
opacity: 1;
pointer-events: auto;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
/* IE can just show/hide with no transition */
.lte8 .wrapper .tooltip {
display: none;
}
.lte8 .wrapper:hover .tooltip {
display: block;
}
</style>
<div id="respond" class="no_webshot">
<div class="comment-signarea" style=" padding: 20px 20px;">
<h3 class="text-muted" id="share_code" style="color: #799961;"><i class="fa fa-pencil-square-o" aria-hidden="true"></i> 点我分享笔记</h3>
<!--
<p style="font-size:14px;">笔记需要是本篇文章的内容扩展!</p><br>
<p style="font-size:12px;"><a href="//www.runoob.com/tougao" target="_blank">文章投稿,可点击这里</a></p>
<p style="font-size:14px;"><a href="/w3cnote/runoob-user-test-intro.html#invite" target="_blank">注册邀请码获取方式</a></p>
<h3 class="text-muted"><i class="fa fa-info-circle" aria-hidden="true"></i> 分享笔记前必须<a href="javascript:;" class="runoob-pop">登录</a>!</h3>
<p><a href="/w3cnote/runoob-user-test-intro.html#invite" target="_blank">注册邀请码获取方式</a></p>-->
</div>
<form action="/wp-content/themes/runoob/option/addnote.php" method="post" id="commentform" style="display:none;">
<div class="comt">
<div class="comt-title">
<i style="font-size:36px;" class="fa fa-user-circle" aria-hidden="true"></i> <p><a id="cancel-comment-reply-link" href="javascript:;">取消</a></p>
</div>
<div class="comt-box">
<div id="mded"></div>
<div class="comt-ctrl">
<div class="comt-tips"><input type=‘hidden‘ name=‘comment_post_ID‘ value=‘4108‘ id=‘comment_post_ID‘ />
<input type=‘hidden‘ name=‘comment_parent‘ id=‘comment_parent‘ value=‘0‘ />
</div>
<button type="submit" name="submit" id="submit" tabindex="5"><i class="fa fa-pencil" aria-hidden="true"></i> 分享笔记</button>
</div>
</div>
<div class="comt-comterinfo">
<ul id="comment-author-info">
<li class="form-inline"><label class="hide" for="author">昵称</label><input class="ipt" type="text" name="author" id="author" value="" tabindex="2" placeholder="昵称"><span class="text-muted">昵称 (必填)</span></li>
<li class="form-inline"><label class="hide" for="email">邮箱</label><input class="ipt" type="text" name="email" id="email" value="" tabindex="3" placeholder="邮箱"><span class="text-muted">邮箱 (必填)</span></li>
<li class="form-inline"><label class="hide" for="url">引用地址</label><input class="ipt" type="text" name="url" id="url" value="" tabindex="4" placeholder="引用地址"><span class="text-muted">引用地址</span></li>
</ul>
</div>
</div>
</form>
</div>
<script type="text/javascript">
$(function() {
//初始化编辑器
var editor = new Simditor({
textarea: $(‘#mded‘),
placeholder: ‘写笔记...‘,
upload:false,
// upload: {url:‘/api/comment_upload_file.php‘,params: null,fileKey: ‘upload_file‘,connectionCount: 1,leaveConfirm: ‘文件正在上传,您确定离开?‘},
defaultImage: ‘http://www.runoob.com/images/logo.png‘,
codeLanguages: ‘‘,
toolbar: [ ‘bold‘,‘code‘,‘ul‘,‘ol‘,‘image‘ ]
});
editor.on(‘selectionchanged‘, function() {
$(".code-popover").hide();
});
// 提交数据
$("#share_code").click(function() {
$(".comment-signarea").hide();
$("#commentform").show();
});
$("#user_add_note").click(function() {
$(".comment-signarea").hide();
$("#commentform").show();
$(‘html, body‘).animate({
scrollTop: $("#respond").offset().top
}, 200);
});
// 提交笔记
var commentform=$(‘#commentform‘);
commentform.prepend(‘<div id="comment-status" style="display:none;" ></div>‘);
var statusdiv=$(‘#comment-status‘);
commentform.submit(function(e){
e.preventDefault();
var noteContent = editor.getValue();
// console.log(noteContent);
noteContent = noteContent.replace(/<pre><code>/g,"<pre>");
noteContent = noteContent.replace(/</code></pre>/g,"</pre>");
// 系列化表单数据
var comment_parent = 0;
var is_user_logged_in = $("#is_user_logged_in").val();
var comment_post_ID = 4108;
var _wp_unfiltered_html_comment = $("#_wp_unfiltered_html_comment").val();
var comment = noteContent;
var author = $("#author").val();
var url = $("#url").val();
var email = $("#email").val();
if(isBlank(author) && is_user_logged_in==0) {
statusdiv.html(‘<p class="ajax-error">请输入昵称!</p>‘).show();
} else if(isBlank(email) && is_user_logged_in==0) {
statusdiv.html(‘<p class="ajax-error">请输入邮箱!</p>‘).show();
} else {
// var formdata=commentform.serialize() + "&comment=" + noteContent ;
// 添加状态信息
statusdiv.html(‘<p>Processing...</p>‘).show();
// 获取表单提交地址
var formurl=commentform.attr(‘action‘);
// 异步提交
$.ajax({
type: ‘post‘,
url: formurl,
dataType:‘json‘,
data: {"comment_parent":comment_parent,"comment_post_ID":comment_post_ID, "_wp_unfiltered_html_comment":_wp_unfiltered_html_comment,"comment":comment,"url":url, "email":email,"author":author},
error: function(XMLHttpRequest, textStatus, errorThrown){
statusdiv.html(‘<p class="ajax-error" >数据不完整或表单提交太快了!</p>‘).show();
},
success: function(data, textStatus){
if(data.errorno=="0") {
$("#submit").prop(‘disabled‘, true);
statusdiv.html(‘<p class="ajax-success" >笔记已提交审核,感谢分享笔记!</p>‘).show();
alert(‘笔记已提交审核,感谢分享笔记!‘);
}else{
statusdiv.html(‘<p class="ajax-error" >‘+data.msg+‘</p>‘).show();
}
commentform.find(‘textarea[name=comment]‘).val(‘‘);
}
});
setTimeout(function(){
$("#submit").prop(‘disabled‘, false);
}, 10*1000);
}
return false;
});
});
function isBlank(str) {
return (!str || /^s*$/.test(str));
}
</script>
<link rel="stylesheet" href="/wp-content/themes/runoob/assets/css/qa.css?1.42">
<link rel="stylesheet" type="text/css" href="//cdn.bootcss.com/simditor/2.3.6/styles/simditor.min.css" />
<script type="text/javascript" src="//static.runoob.com/assets/simditor/2.3.6/scripts/module.js"></script>
<script type="text/javascript" src="//static.runoob.com/assets/simditor/2.3.6/scripts/hotkeys.js"></script>
<script type="text/javascript" src="//static.runoob.com/assets/simditor/2.3.6/scripts/uploader.js"></script>
<script type="text/javascript" src="//cdn.bootcss.com/simditor/2.3.6/lib/simditor.min.js"></script> <div class="sidebar-box ad-box ad-box-large">
<div id="ad-336280" class="ad-336280">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 移动版 自动调整 -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-5751451760833794"
data-ad-slot="1691338467"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
</div>
</div>
<!-- 右边栏 -->
<div class="fivecol last right-column">
<!--
<div class="tab tab-light-blue" style="text-align: center;">关注微信</div>
<div class="sidebar-box">
<a href="http://m.runoob.com/" target="_blank"> <img src="http://www.runoob.com/wp-content/themes/w3cschool.cc/assets/img/qrcode.jpg" alt="移动版"> </a>
<div class="qqinfo">
<a target="_blank" href="http://jq.qq.com/?_wv=1027&k=dOwwKN" id="qqhref">
<img border="0" src="http://pub.idqqimg.com/wpa/images/group.png" alt="菜鸟家族" title="菜鸟家族"></a>
<span>(群号:<span id="qqid">365967760</span>)</span>
</div>
</div>
-->
<style>
.sidebar-tree .double-li {
width:300px;
}
.sidebar-tree .double-li li {
width: 44%;
line-height: 1.5em;
border-bottom: 1px solid #ccc;
float: left;
display: inline;
}
</style>
<div class="sidebar-box ad-box ad-box-large">
<div class="sidebar-box advertise-here" style="margin: 0 auto;">
<a href="javascript:void(0);" style="font-size: 16px; color:#64854c;font-weight:bold;"> <i class="fa fa-list" aria-hidden="true"></i> 分类导航</a>
</div>
<div class="sidebar-box sidebar-cate">
<div class="sidebar-tree" >
<ul><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> HTML / CSS</a><ul class="double-li"><li><a title="HTML 教程" href="//www.runoob.com/html/html-tutorial.html">HTML 教程</a></li><li><a title="HTML5 教程" href="//www.runoob.com/html/html5-intro.html">HTML5 教程</a></li><li><a title="CSS 教程" href="//www.runoob.com/css/css-tutorial.html">CSS 教程</a></li><li><a title="CSS3 教程" href="//www.runoob.com/css3/css3-tutorial.html">CSS3 教程</a></li><li><a title="Bootstrap3 教程" href="//www.runoob.com/bootstrap/bootstrap-tutorial.html">Bootstrap3 教程</a></li><li><a title="Bootstrap4 教程" href="//www.runoob.com/bootstrap4/bootstrap4-tutorial.html">Bootstrap4 教程</a></li><li><a title="Font Awesome 教程" href="//www.runoob.com/font-awesome/fontawesome-tutorial.html">Font Awesome 教程</a></li><li><a title="Foundation 教程" href="//www.runoob.com/foundation/foundation-tutorial.html">Foundation 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> JavaScript</a><ul class="double-li"><li><a title="JavaScript 教程" href="//www.runoob.com/js/js-tutorial.html">JavaScript 教程</a></li><li><a title="HTML DOM 教程" href="//www.runoob.com/htmldom/htmldom-tutorial.html">HTML DOM 教程</a></li><li><a title="jQuery 教程" href="//www.runoob.com/jquery/jquery-tutorial.html">jQuery 教程</a></li><li><a title="AngularJS 教程" href="//www.runoob.com/angularjs/angularjs-tutorial.html">AngularJS 教程</a></li><li><a title="AngularJS2 教程" href="//www.runoob.com/angularjs2/angularjs2-tutorial.html">AngularJS2 教程</a></li><li><a title="Vue.js 教程" href="//www.runoob.com/vue2/vue-tutorial.html">Vue.js 教程</a></li><li><a title="React 教程" href="//www.runoob.com/react/react-tutorial.html">React 教程</a></li><li><a title="jQuery UI 教程" href="//www.runoob.com/jqueryui/jqueryui-tutorial.html">jQuery UI 教程</a></li><li><a title="jQuery EasyUI 教程" href="//www.runoob.com/jeasyui/jqueryeasyui-tutorial.html">jQuery EasyUI 教程</a></li><li><a title="Node.js 教程" href="//www.runoob.com/nodejs/nodejs-tutorial.html">Node.js 教程</a></li><li><a title="AJAX 教程" href="//www.runoob.com/ajax/ajax-tutorial.html">AJAX 教程</a></li><li><a title="JSON 教程" href="//www.runoob.com/json/json-tutorial.html">JSON 教程</a></li><li><a title="Highcharts 教程" href="//www.runoob.com/highcharts/highcharts-tutorial.html">Highcharts 教程</a></li><li><a title="Google 地图 教程" href="//www.runoob.com/googleapi/google-maps-basic.html">Google 地图 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 服务端</a><ul class="double-li"><li><a title="PHP 教程" href="//www.runoob.com/php/php-tutorial.html">PHP 教程</a></li><li><a title="Python 教程" href="//www.runoob.com/python/python-tutorial.html">Python 教程</a></li><li><a title="Python3 教程" href="//www.runoob.com/python3/python3-tutorial.html">Python3 教程</a></li><li><a title="Django 教程" href="//www.runoob.com/django/django-tutorial.html">Django 教程</a></li><li><a title="Linux 教程" href="//www.runoob.com/linux/linux-tutorial.html">Linux 教程</a></li><li><a title="Docker 教程" href="//www.runoob.com/docker/docker-tutorial.html">Docker 教程</a></li><li><a title="Ruby 教程" href="//www.runoob.com/ruby/ruby-tutorial.html">Ruby 教程</a></li><li><a title="Java 教程" href="//www.runoob.com/java/java-tutorial.html">Java 教程</a></li><li><a title="C 教程" href="//www.runoob.com/c/c-tutorial.html">C 教程</a></li><li><a title="C++ 教程" href="//www.runoob.com/cplusplus/cpp-tutorial.html">C++ 教程</a></li><li><a title="Perl 教程" href="//www.runoob.com/perl/perl-tutorial.html">Perl 教程</a></li><li><a title="Servlet 教程" href="//www.runoob.com/servlet/servlet-tutorial.html">Servlet 教程</a></li><li><a title="JSP 教程" href="//www.runoob.com/jsp/jsp-tutorial.html">JSP 教程</a></li><li><a title="Lua 教程" href="//www.runoob.com/lua/lua-tutorial.html">Lua 教程</a></li><li><a title="Scala 教程" href="//www.runoob.com/scala/scala-tutorial.html">Scala 教程</a></li><li><a title="Go 教程" href="//www.runoob.com/go/go-tutorial.html">Go 教程</a></li><li><a title="设计模式" href="//www.runoob.com/design-pattern/design-pattern-tutorial.html">设计模式</a></li><li><a title="正则表达式" href="//www.runoob.com/regexp/regexp-tutorial.html">正则表达式</a></li><li><a title="Maven 教程" href="//www.runoob.com/maven/maven-tutorial.html">Maven 教程</a></li><li><a title="ASP 教程" href="//www.runoob.com/asp/asp-tutorial.html">ASP 教程</a></li><li><a title="AppML 教程" href="//www.runoob.com/appml/appml-tutorial.html">AppML 教程</a></li><li><a title="VBScript 教程" href="//www.runoob.com/vbscript/vbscript-tutorial.html">VBScript 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 数据库</a><ul class="double-li"><li><a title="SQL 教程" href="//www.runoob.com/sql/sql-tutorial.html">SQL 教程</a></li><li><a title="Mysql 教程" href="//www.runoob.com/mysql/mysql-tutorial.html">Mysql 教程</a></li><li><a title="SQLite 教程" href="//www.runoob.com/sqlite/sqlite-tutorial.html">SQLite 教程</a></li><li><a title="MongoDB 教程" href="//www.runoob.com/mongodb/mongodb-tutorial.html">MongoDB 教程</a></li><li><a title="Redis 教程" href="//www.runoob.com/redis/redis-tutorial.html">Redis 教程</a></li><li><a title="Memcached 教程" href="//www.runoob.com/Memcached/Memcached-tutorial.html">Memcached 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 移动端</a><ul class="double-li"><li><a title="Android 教程" href="//www.runoob.com/w3cnote/android-tutorial-intro.html">Android 教程</a></li><li><a title="Swift 教程" href="//www.runoob.com/swift/swift-tutorial.html">Swift 教程</a></li><li><a title="jQuery Mobile 教程" href="//www.runoob.com/jquerymobile/jquerymobile-tutorial.html">jQuery Mobile 教程</a></li><li><a title="ionic 教程" href="//www.runoob.com/ionic/ionic-tutorial.html">ionic 教程</a></li><li><a title="Kotlin 教程" href="//www.runoob.com/kotlin/kotlin-tutorial.html">Kotlin 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> XML 教程</a><ul class="double-li"><li><a title="XML 教程" href="//www.runoob.com/xml/xml-tutorial.html">XML 教程</a></li><li><a title="DTD 教程" href="//www.runoob.com/dtd/dtd-tutorial.html">DTD 教程</a></li><li><a title="XML DOM 教程" href="//www.runoob.com/dom/dom-tutorial.html">XML DOM 教程</a></li><li><a title="XSLT 教程" href="//www.runoob.com/xsl/xsl-tutorial.html">XSLT 教程</a></li><li><a title="XPath 教程" href="//www.runoob.com/xpath/xpath-tutorial.html">XPath 教程</a></li><li><a title="XQuery 教程" href="//www.runoob.com/xquery/xquery-tutorial.html">XQuery 教程</a></li><li><a title="XLink 教程" href="//www.runoob.com/xlink/xlink-tutorial.html">XLink 教程</a></li><li><a title="XPointer 教程" href="//www.runoob.com/xlink/xlink-tutorial.html">XPointer 教程</a></li><li><a title="XML Schema 教程" href="//www.runoob.com/schema/schema-tutorial.html">XML Schema 教程</a></li><li><a title="XSL-FO 教程" href="//www.runoob.com/xslfo/xslfo-tutorial.html">XSL-FO 教程</a></li><li><a title="SVG 教程" href="//www.runoob.com/svg/svg-tutorial.html">SVG 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> ASP.NET</a><ul class="double-li"><li><a title="ASP.NET 教程" href="//www.runoob.com/aspnet/aspnet-tutorial.html">ASP.NET 教程</a></li><li><a title="C# 教程" href="//www.runoob.com/csharp/csharp-tutorial.html">C# 教程</a></li><li><a title="Web Pages 教程" href="//www.runoob.com/aspnet/webpages-intro.html">Web Pages 教程</a></li><li><a title="Razor 教程" href="//www.runoob.com/aspnet/razor-intro.html">Razor 教程</a></li><li><a title="MVC 教程" href="//www.runoob.com/aspnet/mvc-intro.html">MVC 教程</a></li><li><a title="Web Forms 教程" href="//www.runoob.com/aspnet/aspnet-intro.html">Web Forms 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> Web Service</a><ul class="double-li"><li><a title="Web Service 教程" href="//www.runoob.com/webservices/webservices-tutorial.html">Web Service 教程</a></li><li><a title="WSDL 教程" href="//www.runoob.com/wsdl/wsdl-tutorial.html">WSDL 教程</a></li><li><a title="SOAP 教程" href="//www.runoob.com/soap/soap-tutorial.html">SOAP 教程</a></li><li><a title="RSS 教程" href="//www.runoob.com/rss/rss-tutorial.html">RSS 教程</a></li><li><a title="RDF 教程" href="//www.runoob.com/rdf/rdf-tutorial.html">RDF 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 开发工具</a><ul class="double-li"><li><a title="Eclipse 教程" href="//www.runoob.com/eclipse/eclipse-tutorial.html">Eclipse 教程</a></li><li><a title="Git 教程" href="//www.runoob.com/git/git-tutorial.html">Git 教程</a></li><li><a title="Svn 教程" href="//www.runoob.com/svn/svn-tutorial.html">Svn 教程</a></li><li><a title="Firebug 教程" href="//www.runoob.com/firebug/firebug-tutorial.html">Firebug 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 网站建设</a><ul class="double-li"><li><a title="HTTP 教程" href="//www.runoob.com/http/http-tutorial.html">HTTP 教程</a></li><li><a title="网站建设指南" href="//www.runoob.com/web/web-buildingprimer.html">网站建设指南</a></li><li><a title="浏览器信息" href="//www.runoob.com/browsers/browser-information.html">浏览器信息</a></li><li><a title="网站主机教程" href="//www.runoob.com/hosting/hosting-tutorial.html">网站主机教程</a></li><li><a title="TCP/IP 教程" href="//www.runoob.com/tcpip/tcpip-tutorial.html">TCP/IP 教程</a></li><li><a title="W3C 教程" href="//www.runoob.com/w3c/w3c-tutorial.html">W3C 教程</a></li><li><a title="网站品质" href="//www.runoob.com/quality/quality-tutorial.html">网站品质</a></li></ul></li></ul> </div>
</div>
</div>
<br>
<div class="sidebar-box ad-box ad-box-large">
<div class="sidebar-box advertise-here">
<a href="javascript:void(0);">Advertisement</a>
</div>
<div class="ad-600160" id="sidebar-right-ads">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 侧栏1 -->
<ins class="adsbygoogle"
style="display:inline-block;width:160px;height:600px"
data-ad-client="ca-pub-5751451760833794"
data-ad-slot="4106274865"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
</div></div>
</div>
<script>
var aid = 4108;
function coll() {
$.post( ‘/wp-content/themes/runoob/option/user/userinfo.php‘, {aid:aid, action:"collarticle", opt:‘add‘},function( data ) {
if(data.error==0) {
$("#content").find("h1:first").find("a").attr("href","javascript:void(0);");
$("#content").find("h1:first").find("img").attr("src","http://www.runoob.com/wp-content/themes/runoob/assets/img/coll2.png").css({width:32+"px",height:32+"px"});
}
alert(data.msg);
},‘json‘);
}
</script>
<!-- 反馈对话框开始 -->
<script src="/wp-content/themes/runoob/assets/feedback/stable/2.0/feedback.js?1.0"></script>
<link rel="stylesheet" href="/wp-content/themes/runoob/assets/feedback/stable/2.0/feedback.css?1.0" />
<script type="text/javascript">
$.feedback({
ajaxURL: ‘/feedback/runoob_feedback.php‘,
html2canvasURL: ‘/wp-content/themes/runoob/assets/feedback/stable/2.0/html2canvas.js‘
});
</script>
<!-- 反馈对话框结束 -->
<button class="feedback-btn feedback-btn-gray">反馈/建议</button>
<!-- 底部 -->
<div id="footer" class="mar-t50">
<div class="runoob-block">
<div class="runoob cf">
<dl>
<dt>
在线实例
</dt>
<dd>
·<a target="_blank" href="/html/html-examples.html">HTML 实例</a>
</dd>
<dd>
·<a target="_blank" href="/css/css-examples.html">CSS 实例</a>
</dd>
<dd>
·<a target="_blank" href="/js/js-examples.html">JavaScript 实例</a>
</dd>
<dd>
·<a target="_blank" href="/ajx/ajax-examples.html">Ajax 实例</a>
</dd>
<dd>
·<a target="_blank" href="/jquery/jquery-examples.html">jQuery 实例</a>
</dd>
<dd>
·<a target="_blank" href="/xml/xml-examples.html">XML 实例</a>
</dd>
<dd>
·<a target="_blank" href="/java/java-examples.html">Java 实例</a>
</dd>
</dl>
<dl>
<dt>
字符集&工具
</dt>
<dd>
· <a target="_blank" href="/charsets/html-charsets.html">HTML 字符集设置</a>
</dd>
<dd>
· <a target="_blank" href="/tags/html-ascii.html">HTML ASCII 字符集</a>
</dd>
<dd>
· <a target="_blank" href="/tags/ref-entities.html">HTML ISO-8859-1</a>
</dd>
<dd>
· <a target="_blank" href="/tags/html-symbols.html">HTML 实体符号</a>
</dd>
<dd>
· <a target="_blank" href="/tags/html-colorpicker.html">HTML 拾色器</a>
</dd>
<dd>
· <a target="_blank" href="//c.runoob.com/front-end/53">JSON 格式化工具</a>
</dd>
</dl>
<dl>
<dt>
最新更新
</dt>
<dd>
·
<a href="http://www.runoob.com/w3cnote/php-phpmailer.html" title="PHP 使用 phpmailer 发送电子邮件">PHP 使用 phpmai...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/w3cnote/warning-this-program-uses-gets-which-is-unsafe.html" title="C 中使用 gets() 提示 warning: this program uses gets(), which is unsafe.">C 中使用 gets()...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/python3/python3-func-input.html" title="Python3 input() 函数">Python3 input()...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/w3cnote/summary-of-network.html" title="计算机网络基础知识总结">计算机网络基础...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/vue2/vue-examples.html" title="Vue.js 实例">Vue.js 实例</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/python3/ref-set-update.html" title="Python Set update() 方法">Python Set upda...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/python3/ref-set-union.html" title="Python Set union() 方法">Python Set unio...</a>
</dd>
</dl>
<dl>
<dt>
站点信息
</dt>
<dd>
·
<a target="_blank" href="//mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=ssbDyoOAgfLU3crf09venNHd3w" rel="external nofollow">意见反馈</a>
<!--<a class="wxpopup" onclick="popFunction()">合作联系
<span class="popuptext" id="myPopup">微信:<strong>centos5</strong></span>
</a>-->
</dd>
<dd>
·
<a target="_blank" href="/disclaimer">免责声明</a>
</dd>
<!--
<dd style="display: block;">
·
<a href="javascript:void(0)" onclick="dashangToggle()" style="font-weight:bold;color:#f00;" title="打赏,支持一下">打赏一下</a>
</dd>
-->
<dd>
·
<a target="_blank" href="/aboutus">关于我们</a>
</dd>
<dd>
·
<a target="_blank" href="/archives">文章归档</a>
</dd>
<!--
<dd>
·
<a href="https://www.xiaoyouxi100.com/?from=runoob" onclick="_hmt.push([‘_trackEvent‘, ‘小游戏‘, ‘click‘, ‘xiaoyouxi100‘]);" target="_blank" title="小游戏">小游戏</a>
</dd>
-->
</dl>
<div class="search-share">
<div class="app-download">
<div>
<strong>关注微信</strong>
</div>
</div>
<div class="share">
<img width="128" height="128" src="/wp-content/themes/runoob/assets/images/qrcode.png" />
</div>
</div>
</div>
</div>
<div class="w-1000 copyright">
Copyright © 2013-2018 <strong><a href="//www.runoob.com/" target="_blank">菜鸟教程</a></strong>
<strong><a href="//www.runoob.com/" target="_blank">runoob.com</a></strong> All Rights Reserved. 备案号:闽ICP备15012807号-1
</div>
</div>
<div class="fixed-btn">
<a class="go-top" href="javascript:void(0)" title="返回顶部"> <i class="fa fa-angle-up"></i></a>
<a class="qrcode" href="javascript:void(0)" title="关注我们"><i class="fa fa-qrcode"></i></a>
<a class="writer" style="display:none" href="javascript:void(0)" title="标记/收藏"><i class="fa fa-star" aria-hidden="true"></i></a>
<!-- qrcode modal -->
<div id="bottom-qrcode" class="modal panel-modal hide fade in">
<h4>微信关注</h4>
<div class="panel-body"><img alt="微信关注" width="128" height="128" src="/wp-content/themes/runoob/assets/images/qrcode.png"></div>
</div>
</div>
<div class="hide_box"></div>
<div class="shang_box">
<a class="shang_close" href="javascript:void(0)" onclick="dashangToggle()" title="关闭"><img src="//static.runoob.com/images/dashang/close.jpg" alt="取消" /></a>
<div class="shang_tit">
<p>感谢您的支持,我会继续努力的!</p>
</div>
<div class="shang_payimg">
<img src="//static.runoob.com/images/dashang/weipayimg.png" alt="扫码支持" title="扫一扫" />
</div>
<div class="pay_explain">扫码打赏,你说多少就多少</div>
<div class="shang_payselect">
<div class="pay_item checked" data-id="weipay">
<span class="radiobox"></span>
<span class="pay_logo"><img src="//static.runoob.com/images/dashang/wechat.jpg" alt="微信" /></span>
</div>
<div class="pay_item" data-id="alipay">
<span class="radiobox"></span>
<span class="pay_logo"><img src="//static.runoob.com/images/dashang/alipay.jpg" alt="支付宝" /></span>
</div>
</div>
<div class="shang_info">
<p>打开<span id="shang_pay_txt">支付宝</span>扫一扫,即可进行扫码打赏哦</p>
<p><a href="//c.runoob.com/codedemo/5348" target="_blank"><span style=" font-size: 14px;color: #000;font-weight: bold;">点我查看本站打赏源码!</span></a></p>
</div>
</div>
<div id="testClick"></div>
<div style="display:none;">
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?3eec0b7da6548cf07db3bc477ea905ee";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-84264393-2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag(‘js‘, new Date());
gtag(‘config‘, ‘UA-84264393-2‘);
</script>
</div>
<script>
window.jsui={
www: ‘//wwww.runoob.com‘,
uri: ‘//www.runoob.com/wp-content/themes/runoob‘
};
</script>
<style>
ol,ul{list-style:none}.cd-switcher a{text-decoration:none;outline:0}.cd-switcher a:hover{text-decoration:underline}a:focus{outline:0;-moz-outline:0}.main_nav{width:300px;height:60px;margin:60px auto 10px auto}.main_nav li{float:left;width:60px;margin-right:10px;font-size:16px;padding:.6em 1em;border-radius:3em;background:#2f889a;text-align:center}.main_nav li a{color:#fff}.errtip{background-color:#fceaea;color:#db5353;padding:8px 15px;font-size:14px;border:1px solid #fc9797;border-radius:5px}.cd-user-modal{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(52,54,66,0.9);z-index:3;overflow-y:auto;cursor:pointer;visibility:hidden;opacity:0;-webkit-transition:opacity .3s 0,visibility 0 .3s;-moz-transition:opacity .3s 0,visibility 0 .3s;transition:opacity .3s 0,visibility 0 .3s}.cd-user-modal.is-visible{visibility:visible;opacity:1;-webkit-transition:opacity .3s 0,visibility 0 0;-moz-transition:opacity .3s 0,visibility 0 0;transition:opacity .3s 0,visibility 0 0}.cd-user-modal.is-visible .cd-user-modal-container{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}.cd-user-modal-container{position:relative;width:90%;max-width:500px;background:#FFF;margin:3em auto 4em;cursor:auto;border-radius:.25em;-webkit-transform:translateY(-30px);-moz-transform:translateY(-30px);-ms-transform:translateY(-30px);-o-transform:translateY(-30px);transform:translateY(-30px);-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;transition-property:transform;-webkit-transition-duration:.3s;-moz-transition-duration:.3s;transition-duration:.3s}.cd-user-modal-container .cd-switcher:after{content:"";display:table;clear:both}.cd-user-modal-container .cd-switcher li{width:50%;float:left;text-align:center}.cd-user-modal-container .cd-switcher li:first-child a{border-radius:.25em 0 0 0}.cd-user-modal-container .cd-switcher li:last-child a{border-radius:0 .25em 0 0}.cd-user-modal-container .cd-switcher a{font-size:1.2em;font-weight:bold;display:block;width:100%;height:50px;line-height:50px;background:#e8f1e2;color:#96b880}.cd-user-modal-container .cd-switcher a.selected{background:#FFF;color:#505260}@media only screen and (min-width:600px){.cd-user-modal-container{margin:4em auto}.cd-user-modal-container .cd-switcher a{height:70px;line-height:70px}}.cd-form{padding:1.4em}.cd-form .fieldset{position:relative;margin:1.4em 0}.cd-form .fieldset:first-child{margin-top:0}.cd-form .fieldset:last-child{margin-bottom:0}.cd-form label{font-size:16px;font-size:.875rem}.cd-form label.image-replace{display:inline-block;position:absolute;left:15px;top:50%;bottom:auto;-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);height:20px;width:20px;overflow:hidden;text-indent:100%;white-space:nowrap;color:transparent;text-shadow:none;background-repeat:no-repeat;background-position:50% 0}.cd-form label.cd-username{background-image:url("/wp-content/themes/runoob/assets/img/cd-icon-username.svg")}.cd-form label.cd-email{background-image:url("/wp-content/themes/runoob/assets/img/cd-icon-email.svg")}.cd-form label.cd-password{background-image:url("/wp-content/themes/runoob/assets/img/cd-icon-password.svg")}.cd-form input{margin:0;padding:0;border-radius:.25em}.cd-form input.full-width{width:80%}.cd-form input.full-width2{width:94%}.cd-form input.has-padding{padding:12px 20px 12px 50px}.cd-form input.has-border{border:1px solid #d2d8d8;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none}.cd-form input.has-border:focus{border-color:#98b880;box-shadow:0 0 5px rgba(52,54,66,0.1);outline:0}.cd-form input.has-error{border:1px solid #d76666}.cd-form input[type=password]{padding-right:65px}.cd-form input[type=submit]{padding:16px 0;cursor:pointer;background:#96b97d;color:#FFF;font-weight:bold;border:0;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;font-size:1.2em;font-weight:bold}.no-touch .cd-form input[type=submit]:hover,.no-touch .cd-form input[type=submit]:focus{background:#3599ae;outline:0}@media only screen and (min-width:600px){.cd-form{padding:2em}.cd-form .fieldset{margin:2em 0}.cd-form .fieldset:first-child{margin-top:0}.cd-form .fieldset:last-child{margin-bottom:0}.cd-form input.has-padding{padding:16px 20px 16px 50px}.cd-form input[type=submit]{padding:16px 0}}.cd-close-form{display:block;position:absolute;width:40px;height:40px;right:0;top:-40px;background:url("/wp-content/themes/runoob/assets/img/cd-icon-close.svg") no-repeat center center;text-indent:100%;white-space:nowrap;overflow:hidden}@media only screen and (min-width:1170px){}#cd-login,#cd-signup,#cd-reset-password{display:none}#cd-login.is-selected,#cd-signup.is-selected,#cd-reset-password.is-selected{display:block}
</style>
<div class="cd-user-modal">
<div class="cd-user-modal-container">
<ul class="cd-switcher">
<li><a href="javascript:;">用户登录</a></li>
<li><a href="javascript:;">注册新用户</a></li>
</ul>
<div id="cd-login"> <!-- 登录表单 -->
<div class="cd-form">
<p class="fieldset">
<label class="image-replace cd-username" for="signin-username">用户名</label>
<input class="full-width has-padding has-border" id="signin-username" name=username type="text" placeholder="输入用户名">
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signin-password">密码</label>
<input class="full-width has-padding has-border" id="signin-password" name="password" type="password" placeholder="输入密码">
</p>
<p class="fieldset">
<input type="checkbox" id="remember-me" checked>
<label for="remember-me">记住登录状态</label>
<a href="//www.runoob.com/reset-password" style="float: right;padding-right: 20px;" target="_blank">忘记密码?</a>
</p>
<input type="hidden" name="action" value="signin">
<p class="fieldset">
<input class="full-width2" type="submit" value="登 录">
</p>
<div class="err-msg"></div>
</div>
</div>
<div id="cd-signup"> <!-- 注册表单 -->
<div class="cd-form">
<p class="fieldset">
<label class="image-replace cd-password" for="verifycode">邀请码</label>
<input class="full-width has-padding has-border" id="signup-verifycode" name="verifycode" type="text" placeholder="输入邀请码">
</p>
<p class="fieldset">
<label class="image-replace cd-username" for="signup-username">用户名</label>
<input class="full-width has-padding has-border" id="signup-username" name="name" type="text" placeholder="输入用户名">
</p>
<p class="fieldset">
<label class="image-replace cd-email" for="signup-email">邮箱</label>
<input class="full-width has-padding has-border" name="email" id="signup-email" type="email" placeholder="输入mail">
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signup-password">密码</label>
<input class="full-width has-padding has-border" id="signup-password" name="password" type="password" placeholder="输入密码">
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signup-password2">重复输入密码</label>
<input class="full-width has-padding has-border" id="signup-password2" name="password2" type="password" placeholder="重复输入密码">
</p>
<!--
<p class="fieldset">
<input type="checkbox" id="accept-terms">
<label for="accept-terms">我已阅读并同意 <a href="javascript:;">用户协议</a></label>
</p>
-->
<input type="hidden" name="action" value="signup">
<p class="fieldset">
<input class="full-width2" type="submit" value="注册新用户">
</p>
<p class="fieldset">
<a href="//www.runoob.com/w3cnote/runoob-user-test-intro.html#invite" target="_blank">如何获取邀请码?</a>
</p>
<div class="err-msg"></div>
</div>
</div>
<a href="javascript:;" class="cd-close-form">关闭</a>
</div>
</div>
<script src="/wp-content/themes/runoob/assets/js/main.js?v=1.189"></script>
<script src="//static.runoob.com/assets/libs/hl/run_prettify.js"></script>
</body>
</html>
View Code
3.2.1、状态行
HTTP/1.1 200 OK
解析:
协议类型:HTTP/1.1
状态码:200
3.2.2、消息报头
Server: Tengine
Content-Type: text/html
Content-Length: 46318
Connection: keep-alive
Date: Mon, 01 Oct 2018 07:22:39 GMT
X-Powered-By: HHVM/3.28.1
Vary: Accept-Encoding
Via: cache43.l2st3-1[0,200-0,H], cache25.l2st3-1[2,0], kunlun7.cn257[0,200-0,H], kunlun6.cn257[0,0]
Age: 75638
Ali-Swift-Global-Savetime: 1538446306
X-Cache: HIT TCP_MEM_HIT dirn:1:11089010
X-Swift-SaveTime: Tue, 02 Oct 2018 02:11:46 GMT
X-Swift-CacheTime: 86400
Timing-Allow-Origin: *
EagleId: de551ac615384541979717849e
Fiddler软件解析:
3.2.3、空行
3.2.4、响应体(响应正文)
<!Doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta property="qc:admins" content="465267610762567726375" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTTP 教程 | 菜鸟教程</title>
<link rel=‘dns-prefetch‘ href=‘//s.w.org‘ />
<link rel="canonical" href="http://www.runoob.com/http/http-tutorial.html" />
<meta name="keywords" content="HTTP 教程,HTTP">
<meta name="description" content="HTTP 教程 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。 HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。 内容列表 HTTP 简介 本章节介绍了HTTP协议。 HTTP 消息结构 本章节介绍了HTTP消息结构 HTTP 方法 本章节介绍了HTTP的方法,包括..">
<link rel="shortcut icon" href="//static.runoob.com/images/favicon.ico" mce_href="//static.runoob.com/images/favicon.ico" type="image/x-icon" >
<link rel="stylesheet" href="/wp-content/themes/runoob/style.css?v=1.147" type="text/css" media="all" />
<link rel="stylesheet" href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" media="all" />
<!--[if gte IE 9]><!-->
<script src="//cdn.bootcss.com/jquery/2.0.3/jquery.min.js"></script>
<!--<![endif]-->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/html5shiv/r29/html5.min.js"></script>
<![endif]-->
<link rel="apple-touch-icon" href="//static.runoob.com/images/icon/mobile-icon.png"/>
<meta name="apple-mobile-web-app-title" content="菜鸟教程">
</head>
<body>
<!-- 头部 -->
<div class="container logo-search">
<div class="col search row-search-mobile">
<form action="index.php">
<input class="placeholder" placeholder="搜索……" name="s" autocomplete="off">
</form>
</div>
<div class="row">
<div class="col logo">
<h1><a href="/">菜鸟教程 -- 学的不仅是技术,更是梦想!</a></h1>
</div>
<div class="col right-list">
<button class="btn btn-responsive-nav btn-inverse" data-toggle="collapse" data-target=".nav-main-collapse" id="pull" style=""> <i class="fa fa-navicon"></i> </button>
</div>
<div class="col search search-desktop last">
<form action="//www.runoob.com/" target="_blank">
<input class="placeholder" id="s" name="s" placeholder="搜索……" autocomplete="off">
</form>
</div>
</div>
</div>
<!-- 导航栏 -->
<!-- 导航栏 -->
<div class="container navigation">
<div class="row">
<div class="col nav">
<ul class="pc-nav">
<li><a href="//www.runoob.com/">首页</a></li>
<li><a href="/html/html-tutorial.html">HTML</a></li>
<li><a href="/css/css-tutorial.html">CSS</a></li>
<li><a href="/js/js-tutorial.html">JavaScript</a></li>
<li><a href="/jquery/jquery-tutorial.html">jQuery</a></li>
<li><a href="/bootstrap/bootstrap-tutorial.html">Bootstrap</a></li>
<li><a href="/sql/sql-tutorial.html">SQL</a></li>
<li><a href="/mysql/mysql-tutorial.html">MySQL</a></li>
<li><a href="/php/php-tutorial.html">PHP</a></li>
<li><a href="/python/python-tutorial.html">Python2</a></li>
<li><a href="/python3/python3-tutorial.html">Python3</a></li>
<li><a href="/cprogramming/c-tutorial.html">C</a></li>
<li><a href="/cplusplus/cpp-tutorial.html">C++</a></li>
<li><a href="/csharp/csharp-tutorial.html">C#</a></li>
<li><a href="/java/java-tutorial.html">Java</a></li>
<li><a href="/browser-history">本地书签</a></li>
<!--
<li><a href="javascript:;" class="runoob-pop">登录</a></li>
-->
</ul>
<ul class="mobile-nav">
<li><a href="//www.runoob.com/">首页</a></li>
<li><a href="/html/html-tutorial.html">HTML</a></li>
<li><a href="/css/css-tutorial.html">CSS</a></li>
<li><a href="/js/js-tutorial.html">JS</a></li>
<li><a href="/browser-history">本地书签</a></li>
<a href="javascript:void(0)" class="search-reveal">Search</a>
</ul>
</div>
</div>
</div><!-- 内容 -->
<div class="container main">
<!-- 中间 -->
<div class="row">
<div class="col left-column">
<div class="tab">HTTP 教程 <a data-cate="50" href="javascript:void(0);" title="夜间模式" id="moon"><i class="fa fa-moon-o" aria-hidden="true" style="font-size: 1.4em;float: right;margin: 4px 6px 0;"></i></a>
<a data-cate="50" style="display:none;" href="javascript:void(0);" title="日间模式" id="sun" ><i class="fa fa-sun-o" aria-hidden="true" style="font-size: 1.4em;float: right;margin: 4px 6px 0;"></i></a>
</div>
<div class="sidebar-box gallery-list">
<div class="design" id="leftcolumn">
<a target="_top" title="HTTP 教程" href="/http/http-tutorial.html" >
HTTP 教程 </a>
<a target="_top" title="HTTP 简介" href="/http/http-intro.html" >
HTTP 简介 </a>
<a target="_top" title="HTTP 消息结构" href="/http/http-messages.html" >
HTTP 消息结构 </a>
<a target="_top" title="HTTP请求方法" href="/http/http-methods.html" >
HTTP请求方法 </a>
<a target="_top" title="HTTP 响应头信息" href="/http/http-header-fields.html" >
HTTP 响应头信息 </a>
<a target="_top" title="HTTP状态码" href="/http/http-status-codes.html" >
HTTP状态码 </a>
<a target="_top" title="HTTP content-type" href="/http/http-content-type.html" >
HTTP content-type </a>
</div>
</div>
</div> <div class="col middle-column">
<div class="article">
<div class="article-heading-ad" style="display: none;">
</div>
<div class="previous-next-links">
<div class="previous-design-link"><i style="font-size:16px;" class="fa fa-arrow-left" aria-hidden="true"></i> <a href="http://www.runoob.com/http/http-status-codes.html" rel="prev"> HTTP状态码</a> </div>
<div class="next-design-link"><a href="http://www.runoob.com/http/http-content-type.html" rel="next"> HTTP content-type</a> <i style="font-size:16px;" class="fa fa-arrow-right" aria-hidden="true"></i></div>
</div>
<div class="article-body">
<div class="article-intro" id="content">
<h1>HTTP 教程</h1><hr>
<div class="tutintro">
<p>HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。</p>
<p>HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。</p>
</div>
<hr>
<h3><span style="text-decoration: underline;">内容列表</span></h3>
<p><a href="/http/http-intro.html">HTTP 简介</a><br>
本章节介绍了HTTP协议。</p>
<p><a href="/http/http-messages.html">HTTP 消息结构</a><br>
本章节介绍了HTTP消息结构</p>
<p><a href="/http/http-methods.html">HTTP 方法</a><br>
本章节介绍了HTTP的方法,包括 GET, POST, HEAD 等。</p>
<p><a href="/http/http-header-fields.html">HTTP 头信息</a><br>
本章节介绍了HTTP的头信息</p>
<p><a href="/http/http-status-codes.html">HTTP 状态码</a><br>
本章节列出了所有HTTP的状态码。</p>
</div>
</div>
<div class="previous-next-links">
<div class="previous-design-link"><i style="font-size:16px;" class="fa fa-arrow-left" aria-hidden="true"></i> <a href="http://www.runoob.com/http/http-status-codes.html" rel="prev"> HTTP状态码</a> </div>
<div class="next-design-link"><a href="http://www.runoob.com/http/http-content-type.html" rel="next"> HTTP content-type</a> <i style="font-size:16px;" class="fa fa-arrow-right" aria-hidden="true"></i></div>
</div>
<!-- 笔记列表 -->
<style>
.wrapper {
/*text-transform: uppercase; */
background: #ececec;
color: #555;
cursor: help;
font-family: "Gill Sans", Impact, sans-serif;
font-size: 20px;
position: relative;
text-align: center;
width: 200px;
-webkit-transform: translateZ(0); /* webkit flicker fix */
-webkit-font-smoothing: antialiased; /* webkit text rendering fix */
}
.wrapper .tooltip {
white-space: nowrap;
font-size: 14px;
text-align: left;
background: #96b97d;
bottom: 100%;
color: #fff;
display: block;
left: -25px;
margin-bottom: 15px;
opacity: 0;
padding: 14px;
pointer-events: none;
position: absolute;
-webkit-transform: translateY(10px);
-moz-transform: translateY(10px);
-ms-transform: translateY(10px);
-o-transform: translateY(10px);
transform: translateY(10px);
-webkit-transition: all .25s ease-out;
-moz-transition: all .25s ease-out;
-ms-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
-webkit-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
-moz-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
-ms-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
-o-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
}
.tooltip a {
color:#fff;
}
/* This bridges the gap so you can mouse into the tooltip without it disappearing */
.wrapper .tooltip:before {
bottom: -20px;
content: " ";
display: block;
height: 20px;
left: 0;
position: absolute;
width: 100%;
}
/* CSS Triangles - see Trevor‘s post */
.wrapper .tooltip:after {
border-left: solid transparent 10px;
border-right: solid transparent 10px;
border-top: solid #96b97d 10px;
bottom: -10px;
content: " ";
height: 0;
left: 20%;
margin-left: -13px;
position: absolute;
width: 0;
}
.wrapper .tooltip1 {
margin-left: 50px;
padding-top: 0px;
}
.wrapper:hover .tooltip {
opacity: 1;
pointer-events: auto;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
/* IE can just show/hide with no transition */
.lte8 .wrapper .tooltip {
display: none;
}
.lte8 .wrapper:hover .tooltip {
display: block;
}
</style>
<div id="respond" class="no_webshot">
<div class="comment-signarea" style=" padding: 20px 20px;">
<h3 class="text-muted" id="share_code" style="color: #799961;"><i class="fa fa-pencil-square-o" aria-hidden="true"></i> 点我分享笔记</h3>
<!--
<p style="font-size:14px;">笔记需要是本篇文章的内容扩展!</p><br>
<p style="font-size:12px;"><a href="//www.runoob.com/tougao" target="_blank">文章投稿,可点击这里</a></p>
<p style="font-size:14px;"><a href="/w3cnote/runoob-user-test-intro.html#invite" target="_blank">注册邀请码获取方式</a></p>
<h3 class="text-muted"><i class="fa fa-info-circle" aria-hidden="true"></i> 分享笔记前必须<a href="javascript:;" class="runoob-pop">登录</a>!</h3>
<p><a href="/w3cnote/runoob-user-test-intro.html#invite" target="_blank">注册邀请码获取方式</a></p>-->
</div>
<form action="/wp-content/themes/runoob/option/addnote.php" method="post" id="commentform" style="display:none;">
<div class="comt">
<div class="comt-title">
<i style="font-size:36px;" class="fa fa-user-circle" aria-hidden="true"></i> <p><a id="cancel-comment-reply-link" href="javascript:;">取消</a></p>
</div>
<div class="comt-box">
<div id="mded"></div>
<div class="comt-ctrl">
<div class="comt-tips"><input type=‘hidden‘ name=‘comment_post_ID‘ value=‘4108‘ id=‘comment_post_ID‘ />
<input type=‘hidden‘ name=‘comment_parent‘ id=‘comment_parent‘ value=‘0‘ />
</div>
<button type="submit" name="submit" id="submit" tabindex="5"><i class="fa fa-pencil" aria-hidden="true"></i> 分享笔记</button>
</div>
</div>
<div class="comt-comterinfo">
<ul id="comment-author-info">
<li class="form-inline"><label class="hide" for="author">昵称</label><input class="ipt" type="text" name="author" id="author" value="" tabindex="2" placeholder="昵称"><span class="text-muted">昵称 (必填)</span></li>
<li class="form-inline"><label class="hide" for="email">邮箱</label><input class="ipt" type="text" name="email" id="email" value="" tabindex="3" placeholder="邮箱"><span class="text-muted">邮箱 (必填)</span></li>
<li class="form-inline"><label class="hide" for="url">引用地址</label><input class="ipt" type="text" name="url" id="url" value="" tabindex="4" placeholder="引用地址"><span class="text-muted">引用地址</span></li>
</ul>
</div>
</div>
</form>
</div>
<script type="text/javascript">
$(function() {
//初始化编辑器
var editor = new Simditor({
textarea: $(‘#mded‘),
placeholder: ‘写笔记...‘,
upload:false,
// upload: {url:‘/api/comment_upload_file.php‘,params: null,fileKey: ‘upload_file‘,connectionCount: 1,leaveConfirm: ‘文件正在上传,您确定离开?‘},
defaultImage: ‘http://www.runoob.com/images/logo.png‘,
codeLanguages: ‘‘,
toolbar: [ ‘bold‘,‘code‘,‘ul‘,‘ol‘,‘image‘ ]
});
editor.on(‘selectionchanged‘, function() {
$(".code-popover").hide();
});
// 提交数据
$("#share_code").click(function() {
$(".comment-signarea").hide();
$("#commentform").show();
});
$("#user_add_note").click(function() {
$(".comment-signarea").hide();
$("#commentform").show();
$(‘html, body‘).animate({
scrollTop: $("#respond").offset().top
}, 200);
});
// 提交笔记
var commentform=$(‘#commentform‘);
commentform.prepend(‘<div id="comment-status" style="display:none;" ></div>‘);
var statusdiv=$(‘#comment-status‘);
commentform.submit(function(e){
e.preventDefault();
var noteContent = editor.getValue();
// console.log(noteContent);
noteContent = noteContent.replace(/<pre><code>/g,"<pre>");
noteContent = noteContent.replace(/</code></pre>/g,"</pre>");
// 系列化表单数据
var comment_parent = 0;
var is_user_logged_in = $("#is_user_logged_in").val();
var comment_post_ID = 4108;
var _wp_unfiltered_html_comment = $("#_wp_unfiltered_html_comment").val();
var comment = noteContent;
var author = $("#author").val();
var url = $("#url").val();
var email = $("#email").val();
if(isBlank(author) && is_user_logged_in==0) {
statusdiv.html(‘<p class="ajax-error">请输入昵称!</p>‘).show();
} else if(isBlank(email) && is_user_logged_in==0) {
statusdiv.html(‘<p class="ajax-error">请输入邮箱!</p>‘).show();
} else {
// var formdata=commentform.serialize() + "&comment=" + noteContent ;
// 添加状态信息
statusdiv.html(‘<p>Processing...</p>‘).show();
// 获取表单提交地址
var formurl=commentform.attr(‘action‘);
// 异步提交
$.ajax({
type: ‘post‘,
url: formurl,
dataType:‘json‘,
data: {"comment_parent":comment_parent,"comment_post_ID":comment_post_ID, "_wp_unfiltered_html_comment":_wp_unfiltered_html_comment,"comment":comment,"url":url, "email":email,"author":author},
error: function(XMLHttpRequest, textStatus, errorThrown){
statusdiv.html(‘<p class="ajax-error" >数据不完整或表单提交太快了!</p>‘).show();
},
success: function(data, textStatus){
if(data.errorno=="0") {
$("#submit").prop(‘disabled‘, true);
statusdiv.html(‘<p class="ajax-success" >笔记已提交审核,感谢分享笔记!</p>‘).show();
alert(‘笔记已提交审核,感谢分享笔记!‘);
}else{
statusdiv.html(‘<p class="ajax-error" >‘+data.msg+‘</p>‘).show();
}
commentform.find(‘textarea[name=comment]‘).val(‘‘);
}
});
setTimeout(function(){
$("#submit").prop(‘disabled‘, false);
}, 10*1000);
}
return false;
});
});
function isBlank(str) {
return (!str || /^s*$/.test(str));
}
</script>
<link rel="stylesheet" href="/wp-content/themes/runoob/assets/css/qa.css?1.42">
<link rel="stylesheet" type="text/css" href="//cdn.bootcss.com/simditor/2.3.6/styles/simditor.min.css" />
<script type="text/javascript" src="//static.runoob.com/assets/simditor/2.3.6/scripts/module.js"></script>
<script type="text/javascript" src="//static.runoob.com/assets/simditor/2.3.6/scripts/hotkeys.js"></script>
<script type="text/javascript" src="//static.runoob.com/assets/simditor/2.3.6/scripts/uploader.js"></script>
<script type="text/javascript" src="//cdn.bootcss.com/simditor/2.3.6/lib/simditor.min.js"></script> <div class="sidebar-box ad-box ad-box-large">
<div id="ad-336280" class="ad-336280">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 移动版 自动调整 -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-5751451760833794"
data-ad-slot="1691338467"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
</div>
</div>
<!-- 右边栏 -->
<div class="fivecol last right-column">
<!--
<div class="tab tab-light-blue" style="text-align: center;">关注微信</div>
<div class="sidebar-box">
<a href="http://m.runoob.com/" target="_blank"> <img src="http://www.runoob.com/wp-content/themes/w3cschool.cc/assets/img/qrcode.jpg" alt="移动版"> </a>
<div class="qqinfo">
<a target="_blank" href="http://jq.qq.com/?_wv=1027&k=dOwwKN" id="qqhref">
<img border="0" src="http://pub.idqqimg.com/wpa/images/group.png" alt="菜鸟家族" title="菜鸟家族"></a>
<span>(群号:<span id="qqid">365967760</span>)</span>
</div>
</div>
-->
<style>
.sidebar-tree .double-li {
width:300px;
}
.sidebar-tree .double-li li {
width: 44%;
line-height: 1.5em;
border-bottom: 1px solid #ccc;
float: left;
display: inline;
}
</style>
<div class="sidebar-box ad-box ad-box-large">
<div class="sidebar-box advertise-here" style="margin: 0 auto;">
<a href="javascript:void(0);" style="font-size: 16px; color:#64854c;font-weight:bold;"> <i class="fa fa-list" aria-hidden="true"></i> 分类导航</a>
</div>
<div class="sidebar-box sidebar-cate">
<div class="sidebar-tree" >
<ul><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> HTML / CSS</a><ul class="double-li"><li><a title="HTML 教程" href="//www.runoob.com/html/html-tutorial.html">HTML 教程</a></li><li><a title="HTML5 教程" href="//www.runoob.com/html/html5-intro.html">HTML5 教程</a></li><li><a title="CSS 教程" href="//www.runoob.com/css/css-tutorial.html">CSS 教程</a></li><li><a title="CSS3 教程" href="//www.runoob.com/css3/css3-tutorial.html">CSS3 教程</a></li><li><a title="Bootstrap3 教程" href="//www.runoob.com/bootstrap/bootstrap-tutorial.html">Bootstrap3 教程</a></li><li><a title="Bootstrap4 教程" href="//www.runoob.com/bootstrap4/bootstrap4-tutorial.html">Bootstrap4 教程</a></li><li><a title="Font Awesome 教程" href="//www.runoob.com/font-awesome/fontawesome-tutorial.html">Font Awesome 教程</a></li><li><a title="Foundation 教程" href="//www.runoob.com/foundation/foundation-tutorial.html">Foundation 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> JavaScript</a><ul class="double-li"><li><a title="JavaScript 教程" href="//www.runoob.com/js/js-tutorial.html">JavaScript 教程</a></li><li><a title="HTML DOM 教程" href="//www.runoob.com/htmldom/htmldom-tutorial.html">HTML DOM 教程</a></li><li><a title="jQuery 教程" href="//www.runoob.com/jquery/jquery-tutorial.html">jQuery 教程</a></li><li><a title="AngularJS 教程" href="//www.runoob.com/angularjs/angularjs-tutorial.html">AngularJS 教程</a></li><li><a title="AngularJS2 教程" href="//www.runoob.com/angularjs2/angularjs2-tutorial.html">AngularJS2 教程</a></li><li><a title="Vue.js 教程" href="//www.runoob.com/vue2/vue-tutorial.html">Vue.js 教程</a></li><li><a title="React 教程" href="//www.runoob.com/react/react-tutorial.html">React 教程</a></li><li><a title="jQuery UI 教程" href="//www.runoob.com/jqueryui/jqueryui-tutorial.html">jQuery UI 教程</a></li><li><a title="jQuery EasyUI 教程" href="//www.runoob.com/jeasyui/jqueryeasyui-tutorial.html">jQuery EasyUI 教程</a></li><li><a title="Node.js 教程" href="//www.runoob.com/nodejs/nodejs-tutorial.html">Node.js 教程</a></li><li><a title="AJAX 教程" href="//www.runoob.com/ajax/ajax-tutorial.html">AJAX 教程</a></li><li><a title="JSON 教程" href="//www.runoob.com/json/json-tutorial.html">JSON 教程</a></li><li><a title="Highcharts 教程" href="//www.runoob.com/highcharts/highcharts-tutorial.html">Highcharts 教程</a></li><li><a title="Google 地图 教程" href="//www.runoob.com/googleapi/google-maps-basic.html">Google 地图 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 服务端</a><ul class="double-li"><li><a title="PHP 教程" href="//www.runoob.com/php/php-tutorial.html">PHP 教程</a></li><li><a title="Python 教程" href="//www.runoob.com/python/python-tutorial.html">Python 教程</a></li><li><a title="Python3 教程" href="//www.runoob.com/python3/python3-tutorial.html">Python3 教程</a></li><li><a title="Django 教程" href="//www.runoob.com/django/django-tutorial.html">Django 教程</a></li><li><a title="Linux 教程" href="//www.runoob.com/linux/linux-tutorial.html">Linux 教程</a></li><li><a title="Docker 教程" href="//www.runoob.com/docker/docker-tutorial.html">Docker 教程</a></li><li><a title="Ruby 教程" href="//www.runoob.com/ruby/ruby-tutorial.html">Ruby 教程</a></li><li><a title="Java 教程" href="//www.runoob.com/java/java-tutorial.html">Java 教程</a></li><li><a title="C 教程" href="//www.runoob.com/c/c-tutorial.html">C 教程</a></li><li><a title="C++ 教程" href="//www.runoob.com/cplusplus/cpp-tutorial.html">C++ 教程</a></li><li><a title="Perl 教程" href="//www.runoob.com/perl/perl-tutorial.html">Perl 教程</a></li><li><a title="Servlet 教程" href="//www.runoob.com/servlet/servlet-tutorial.html">Servlet 教程</a></li><li><a title="JSP 教程" href="//www.runoob.com/jsp/jsp-tutorial.html">JSP 教程</a></li><li><a title="Lua 教程" href="//www.runoob.com/lua/lua-tutorial.html">Lua 教程</a></li><li><a title="Scala 教程" href="//www.runoob.com/scala/scala-tutorial.html">Scala 教程</a></li><li><a title="Go 教程" href="//www.runoob.com/go/go-tutorial.html">Go 教程</a></li><li><a title="设计模式" href="//www.runoob.com/design-pattern/design-pattern-tutorial.html">设计模式</a></li><li><a title="正则表达式" href="//www.runoob.com/regexp/regexp-tutorial.html">正则表达式</a></li><li><a title="Maven 教程" href="//www.runoob.com/maven/maven-tutorial.html">Maven 教程</a></li><li><a title="ASP 教程" href="//www.runoob.com/asp/asp-tutorial.html">ASP 教程</a></li><li><a title="AppML 教程" href="//www.runoob.com/appml/appml-tutorial.html">AppML 教程</a></li><li><a title="VBScript 教程" href="//www.runoob.com/vbscript/vbscript-tutorial.html">VBScript 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 数据库</a><ul class="double-li"><li><a title="SQL 教程" href="//www.runoob.com/sql/sql-tutorial.html">SQL 教程</a></li><li><a title="Mysql 教程" href="//www.runoob.com/mysql/mysql-tutorial.html">Mysql 教程</a></li><li><a title="SQLite 教程" href="//www.runoob.com/sqlite/sqlite-tutorial.html">SQLite 教程</a></li><li><a title="MongoDB 教程" href="//www.runoob.com/mongodb/mongodb-tutorial.html">MongoDB 教程</a></li><li><a title="Redis 教程" href="//www.runoob.com/redis/redis-tutorial.html">Redis 教程</a></li><li><a title="Memcached 教程" href="//www.runoob.com/Memcached/Memcached-tutorial.html">Memcached 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 移动端</a><ul class="double-li"><li><a title="Android 教程" href="//www.runoob.com/w3cnote/android-tutorial-intro.html">Android 教程</a></li><li><a title="Swift 教程" href="//www.runoob.com/swift/swift-tutorial.html">Swift 教程</a></li><li><a title="jQuery Mobile 教程" href="//www.runoob.com/jquerymobile/jquerymobile-tutorial.html">jQuery Mobile 教程</a></li><li><a title="ionic 教程" href="//www.runoob.com/ionic/ionic-tutorial.html">ionic 教程</a></li><li><a title="Kotlin 教程" href="//www.runoob.com/kotlin/kotlin-tutorial.html">Kotlin 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> XML 教程</a><ul class="double-li"><li><a title="XML 教程" href="//www.runoob.com/xml/xml-tutorial.html">XML 教程</a></li><li><a title="DTD 教程" href="//www.runoob.com/dtd/dtd-tutorial.html">DTD 教程</a></li><li><a title="XML DOM 教程" href="//www.runoob.com/dom/dom-tutorial.html">XML DOM 教程</a></li><li><a title="XSLT 教程" href="//www.runoob.com/xsl/xsl-tutorial.html">XSLT 教程</a></li><li><a title="XPath 教程" href="//www.runoob.com/xpath/xpath-tutorial.html">XPath 教程</a></li><li><a title="XQuery 教程" href="//www.runoob.com/xquery/xquery-tutorial.html">XQuery 教程</a></li><li><a title="XLink 教程" href="//www.runoob.com/xlink/xlink-tutorial.html">XLink 教程</a></li><li><a title="XPointer 教程" href="//www.runoob.com/xlink/xlink-tutorial.html">XPointer 教程</a></li><li><a title="XML Schema 教程" href="//www.runoob.com/schema/schema-tutorial.html">XML Schema 教程</a></li><li><a title="XSL-FO 教程" href="//www.runoob.com/xslfo/xslfo-tutorial.html">XSL-FO 教程</a></li><li><a title="SVG 教程" href="//www.runoob.com/svg/svg-tutorial.html">SVG 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> ASP.NET</a><ul class="double-li"><li><a title="ASP.NET 教程" href="//www.runoob.com/aspnet/aspnet-tutorial.html">ASP.NET 教程</a></li><li><a title="C# 教程" href="//www.runoob.com/csharp/csharp-tutorial.html">C# 教程</a></li><li><a title="Web Pages 教程" href="//www.runoob.com/aspnet/webpages-intro.html">Web Pages 教程</a></li><li><a title="Razor 教程" href="//www.runoob.com/aspnet/razor-intro.html">Razor 教程</a></li><li><a title="MVC 教程" href="//www.runoob.com/aspnet/mvc-intro.html">MVC 教程</a></li><li><a title="Web Forms 教程" href="//www.runoob.com/aspnet/aspnet-intro.html">Web Forms 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> Web Service</a><ul class="double-li"><li><a title="Web Service 教程" href="//www.runoob.com/webservices/webservices-tutorial.html">Web Service 教程</a></li><li><a title="WSDL 教程" href="//www.runoob.com/wsdl/wsdl-tutorial.html">WSDL 教程</a></li><li><a title="SOAP 教程" href="//www.runoob.com/soap/soap-tutorial.html">SOAP 教程</a></li><li><a title="RSS 教程" href="//www.runoob.com/rss/rss-tutorial.html">RSS 教程</a></li><li><a title="RDF 教程" href="//www.runoob.com/rdf/rdf-tutorial.html">RDF 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 开发工具</a><ul class="double-li"><li><a title="Eclipse 教程" href="//www.runoob.com/eclipse/eclipse-tutorial.html">Eclipse 教程</a></li><li><a title="Git 教程" href="//www.runoob.com/git/git-tutorial.html">Git 教程</a></li><li><a title="Svn 教程" href="//www.runoob.com/svn/svn-tutorial.html">Svn 教程</a></li><li><a title="Firebug 教程" href="//www.runoob.com/firebug/firebug-tutorial.html">Firebug 教程</a></li></ul></li><li style="margin: 0;"><a href="javascript:void(0);" class="tit"> 网站建设</a><ul class="double-li"><li><a title="HTTP 教程" href="//www.runoob.com/http/http-tutorial.html">HTTP 教程</a></li><li><a title="网站建设指南" href="//www.runoob.com/web/web-buildingprimer.html">网站建设指南</a></li><li><a title="浏览器信息" href="//www.runoob.com/browsers/browser-information.html">浏览器信息</a></li><li><a title="网站主机教程" href="//www.runoob.com/hosting/hosting-tutorial.html">网站主机教程</a></li><li><a title="TCP/IP 教程" href="//www.runoob.com/tcpip/tcpip-tutorial.html">TCP/IP 教程</a></li><li><a title="W3C 教程" href="//www.runoob.com/w3c/w3c-tutorial.html">W3C 教程</a></li><li><a title="网站品质" href="//www.runoob.com/quality/quality-tutorial.html">网站品质</a></li></ul></li></ul> </div>
</div>
</div>
<br>
<div class="sidebar-box ad-box ad-box-large">
<div class="sidebar-box advertise-here">
<a href="javascript:void(0);">Advertisement</a>
</div>
<div class="ad-600160" id="sidebar-right-ads">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- 侧栏1 -->
<ins class="adsbygoogle"
style="display:inline-block;width:160px;height:600px"
data-ad-client="ca-pub-5751451760833794"
data-ad-slot="4106274865"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
</div></div>
</div>
<script>
var aid = 4108;
function coll() {
$.post( ‘/wp-content/themes/runoob/option/user/userinfo.php‘, {aid:aid, action:"collarticle", opt:‘add‘},function( data ) {
if(data.error==0) {
$("#content").find("h1:first").find("a").attr("href","javascript:void(0);");
$("#content").find("h1:first").find("img").attr("src","http://www.runoob.com/wp-content/themes/runoob/assets/img/coll2.png").css({width:32+"px",height:32+"px"});
}
alert(data.msg);
},‘json‘);
}
</script>
<!-- 反馈对话框开始 -->
<script src="/wp-content/themes/runoob/assets/feedback/stable/2.0/feedback.js?1.0"></script>
<link rel="stylesheet" href="/wp-content/themes/runoob/assets/feedback/stable/2.0/feedback.css?1.0" />
<script type="text/javascript">
$.feedback({
ajaxURL: ‘/feedback/runoob_feedback.php‘,
html2canvasURL: ‘/wp-content/themes/runoob/assets/feedback/stable/2.0/html2canvas.js‘
});
</script>
<!-- 反馈对话框结束 -->
<button class="feedback-btn feedback-btn-gray">反馈/建议</button>
<!-- 底部 -->
<div id="footer" class="mar-t50">
<div class="runoob-block">
<div class="runoob cf">
<dl>
<dt>
在线实例
</dt>
<dd>
·<a target="_blank" href="/html/html-examples.html">HTML 实例</a>
</dd>
<dd>
·<a target="_blank" href="/css/css-examples.html">CSS 实例</a>
</dd>
<dd>
·<a target="_blank" href="/js/js-examples.html">JavaScript 实例</a>
</dd>
<dd>
·<a target="_blank" href="/ajx/ajax-examples.html">Ajax 实例</a>
</dd>
<dd>
·<a target="_blank" href="/jquery/jquery-examples.html">jQuery 实例</a>
</dd>
<dd>
·<a target="_blank" href="/xml/xml-examples.html">XML 实例</a>
</dd>
<dd>
·<a target="_blank" href="/java/java-examples.html">Java 实例</a>
</dd>
</dl>
<dl>
<dt>
字符集&工具
</dt>
<dd>
· <a target="_blank" href="/charsets/html-charsets.html">HTML 字符集设置</a>
</dd>
<dd>
· <a target="_blank" href="/tags/html-ascii.html">HTML ASCII 字符集</a>
</dd>
<dd>
· <a target="_blank" href="/tags/ref-entities.html">HTML ISO-8859-1</a>
</dd>
<dd>
· <a target="_blank" href="/tags/html-symbols.html">HTML 实体符号</a>
</dd>
<dd>
· <a target="_blank" href="/tags/html-colorpicker.html">HTML 拾色器</a>
</dd>
<dd>
· <a target="_blank" href="//c.runoob.com/front-end/53">JSON 格式化工具</a>
</dd>
</dl>
<dl>
<dt>
最新更新
</dt>
<dd>
·
<a href="http://www.runoob.com/w3cnote/php-phpmailer.html" title="PHP 使用 phpmailer 发送电子邮件">PHP 使用 phpmai...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/w3cnote/warning-this-program-uses-gets-which-is-unsafe.html" title="C 中使用 gets() 提示 warning: this program uses gets(), which is unsafe.">C 中使用 gets()...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/python3/python3-func-input.html" title="Python3 input() 函数">Python3 input()...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/w3cnote/summary-of-network.html" title="计算机网络基础知识总结">计算机网络基础...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/vue2/vue-examples.html" title="Vue.js 实例">Vue.js 实例</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/python3/ref-set-update.html" title="Python Set update() 方法">Python Set upda...</a>
</dd>
<dd>
·
<a href="http://www.runoob.com/python3/ref-set-union.html" title="Python Set union() 方法">Python Set unio...</a>
</dd>
</dl>
<dl>
<dt>
站点信息
</dt>
<dd>
·
<a target="_blank" href="//mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=ssbDyoOAgfLU3crf09venNHd3w" rel="external nofollow">意见反馈</a>
<!--<a class="wxpopup" onclick="popFunction()">合作联系
<span class="popuptext" id="myPopup">微信:<strong>centos5</strong></span>
</a>-->
</dd>
<dd>
·
<a target="_blank" href="/disclaimer">免责声明</a>
</dd>
<!--
<dd style="display: block;">
·
<a href="javascript:void(0)" onclick="dashangToggle()" style="font-weight:bold;color:#f00;" title="打赏,支持一下">打赏一下</a>
</dd>
-->
<dd>
·
<a target="_blank" href="/aboutus">关于我们</a>
</dd>
<dd>
·
<a target="_blank" href="/archives">文章归档</a>
</dd>
<!--
<dd>
·
<a href="https://www.xiaoyouxi100.com/?from=runoob" onclick="_hmt.push([‘_trackEvent‘, ‘小游戏‘, ‘click‘, ‘xiaoyouxi100‘]);" target="_blank" title="小游戏">小游戏</a>
</dd>
-->
</dl>
<div class="search-share">
<div class="app-download">
<div>
<strong>关注微信</strong>
</div>
</div>
<div class="share">
<img width="128" height="128" src="/wp-content/themes/runoob/assets/images/qrcode.png" />
</div>
</div>
</div>
</div>
<div class="w-1000 copyright">
Copyright © 2013-2018 <strong><a href="//www.runoob.com/" target="_blank">菜鸟教程</a></strong>
<strong><a href="//www.runoob.com/" target="_blank">runoob.com</a></strong> All Rights Reserved. 备案号:闽ICP备15012807号-1
</div>
</div>
<div class="fixed-btn">
<a class="go-top" href="javascript:void(0)" title="返回顶部"> <i class="fa fa-angle-up"></i></a>
<a class="qrcode" href="javascript:void(0)" title="关注我们"><i class="fa fa-qrcode"></i></a>
<a class="writer" style="display:none" href="javascript:void(0)" title="标记/收藏"><i class="fa fa-star" aria-hidden="true"></i></a>
<!-- qrcode modal -->
<div id="bottom-qrcode" class="modal panel-modal hide fade in">
<h4>微信关注</h4>
<div class="panel-body"><img alt="微信关注" width="128" height="128" src="/wp-content/themes/runoob/assets/images/qrcode.png"></div>
</div>
</div>
<div class="hide_box"></div>
<div class="shang_box">
<a class="shang_close" href="javascript:void(0)" onclick="dashangToggle()" title="关闭"><img src="//static.runoob.com/images/dashang/close.jpg" alt="取消" /></a>
<div class="shang_tit">
<p>感谢您的支持,我会继续努力的!</p>
</div>
<div class="shang_payimg">
<img src="//static.runoob.com/images/dashang/weipayimg.png" alt="扫码支持" title="扫一扫" />
</div>
<div class="pay_explain">扫码打赏,你说多少就多少</div>
<div class="shang_payselect">
<div class="pay_item checked" data-id="weipay">
<span class="radiobox"></span>
<span class="pay_logo"><img src="//static.runoob.com/images/dashang/wechat.jpg" alt="微信" /></span>
</div>
<div class="pay_item" data-id="alipay">
<span class="radiobox"></span>
<span class="pay_logo"><img src="//static.runoob.com/images/dashang/alipay.jpg" alt="支付宝" /></span>
</div>
</div>
<div class="shang_info">
<p>打开<span id="shang_pay_txt">支付宝</span>扫一扫,即可进行扫码打赏哦</p>
<p><a href="//c.runoob.com/codedemo/5348" target="_blank"><span style=" font-size: 14px;color: #000;font-weight: bold;">点我查看本站打赏源码!</span></a></p>
</div>
</div>
<div id="testClick"></div>
<div style="display:none;">
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?3eec0b7da6548cf07db3bc477ea905ee";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-84264393-2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag(‘js‘, new Date());
gtag(‘config‘, ‘UA-84264393-2‘);
</script>
</div>
<script>
window.jsui={
www: ‘//wwww.runoob.com‘,
uri: ‘//www.runoob.com/wp-content/themes/runoob‘
};
</script>
<style>
ol,ul{list-style:none}.cd-switcher a{text-decoration:none;outline:0}.cd-switcher a:hover{text-decoration:underline}a:focus{outline:0;-moz-outline:0}.main_nav{width:300px;height:60px;margin:60px auto 10px auto}.main_nav li{float:left;width:60px;margin-right:10px;font-size:16px;padding:.6em 1em;border-radius:3em;background:#2f889a;text-align:center}.main_nav li a{color:#fff}.errtip{background-color:#fceaea;color:#db5353;padding:8px 15px;font-size:14px;border:1px solid #fc9797;border-radius:5px}.cd-user-modal{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(52,54,66,0.9);z-index:3;overflow-y:auto;cursor:pointer;visibility:hidden;opacity:0;-webkit-transition:opacity .3s 0,visibility 0 .3s;-moz-transition:opacity .3s 0,visibility 0 .3s;transition:opacity .3s 0,visibility 0 .3s}.cd-user-modal.is-visible{visibility:visible;opacity:1;-webkit-transition:opacity .3s 0,visibility 0 0;-moz-transition:opacity .3s 0,visibility 0 0;transition:opacity .3s 0,visibility 0 0}.cd-user-modal.is-visible .cd-user-modal-container{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}.cd-user-modal-container{position:relative;width:90%;max-width:500px;background:#FFF;margin:3em auto 4em;cursor:auto;border-radius:.25em;-webkit-transform:translateY(-30px);-moz-transform:translateY(-30px);-ms-transform:translateY(-30px);-o-transform:translateY(-30px);transform:translateY(-30px);-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;transition-property:transform;-webkit-transition-duration:.3s;-moz-transition-duration:.3s;transition-duration:.3s}.cd-user-modal-container .cd-switcher:after{content:"";display:table;clear:both}.cd-user-modal-container .cd-switcher li{width:50%;float:left;text-align:center}.cd-user-modal-container .cd-switcher li:first-child a{border-radius:.25em 0 0 0}.cd-user-modal-container .cd-switcher li:last-child a{border-radius:0 .25em 0 0}.cd-user-modal-container .cd-switcher a{font-size:1.2em;font-weight:bold;display:block;width:100%;height:50px;line-height:50px;background:#e8f1e2;color:#96b880}.cd-user-modal-container .cd-switcher a.selected{background:#FFF;color:#505260}@media only screen and (min-width:600px){.cd-user-modal-container{margin:4em auto}.cd-user-modal-container .cd-switcher a{height:70px;line-height:70px}}.cd-form{padding:1.4em}.cd-form .fieldset{position:relative;margin:1.4em 0}.cd-form .fieldset:first-child{margin-top:0}.cd-form .fieldset:last-child{margin-bottom:0}.cd-form label{font-size:16px;font-size:.875rem}.cd-form label.image-replace{display:inline-block;position:absolute;left:15px;top:50%;bottom:auto;-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);height:20px;width:20px;overflow:hidden;text-indent:100%;white-space:nowrap;color:transparent;text-shadow:none;background-repeat:no-repeat;background-position:50% 0}.cd-form label.cd-username{background-image:url("/wp-content/themes/runoob/assets/img/cd-icon-username.svg")}.cd-form label.cd-email{background-image:url("/wp-content/themes/runoob/assets/img/cd-icon-email.svg")}.cd-form label.cd-password{background-image:url("/wp-content/themes/runoob/assets/img/cd-icon-password.svg")}.cd-form input{margin:0;padding:0;border-radius:.25em}.cd-form input.full-width{width:80%}.cd-form input.full-width2{width:94%}.cd-form input.has-padding{padding:12px 20px 12px 50px}.cd-form input.has-border{border:1px solid #d2d8d8;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none}.cd-form input.has-border:focus{border-color:#98b880;box-shadow:0 0 5px rgba(52,54,66,0.1);outline:0}.cd-form input.has-error{border:1px solid #d76666}.cd-form input[type=password]{padding-right:65px}.cd-form input[type=submit]{padding:16px 0;cursor:pointer;background:#96b97d;color:#FFF;font-weight:bold;border:0;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;font-size:1.2em;font-weight:bold}.no-touch .cd-form input[type=submit]:hover,.no-touch .cd-form input[type=submit]:focus{background:#3599ae;outline:0}@media only screen and (min-width:600px){.cd-form{padding:2em}.cd-form .fieldset{margin:2em 0}.cd-form .fieldset:first-child{margin-top:0}.cd-form .fieldset:last-child{margin-bottom:0}.cd-form input.has-padding{padding:16px 20px 16px 50px}.cd-form input[type=submit]{padding:16px 0}}.cd-close-form{display:block;position:absolute;width:40px;height:40px;right:0;top:-40px;background:url("/wp-content/themes/runoob/assets/img/cd-icon-close.svg") no-repeat center center;text-indent:100%;white-space:nowrap;overflow:hidden}@media only screen and (min-width:1170px){}#cd-login,#cd-signup,#cd-reset-password{display:none}#cd-login.is-selected,#cd-signup.is-selected,#cd-reset-password.is-selected{display:block}
</style>
<div class="cd-user-modal">
<div class="cd-user-modal-container">
<ul class="cd-switcher">
<li><a href="javascript:;">用户登录</a></li>
<li><a href="javascript:;">注册新用户</a></li>
</ul>
<div id="cd-login"> <!-- 登录表单 -->
<div class="cd-form">
<p class="fieldset">
<label class="image-replace cd-username" for="signin-username">用户名</label>
<input class="full-width has-padding has-border" id="signin-username" name=username type="text" placeholder="输入用户名">
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signin-password">密码</label>
<input class="full-width has-padding has-border" id="signin-password" name="password" type="password" placeholder="输入密码">
</p>
<p class="fieldset">
<input type="checkbox" id="remember-me" checked>
<label for="remember-me">记住登录状态</label>
<a href="//www.runoob.com/reset-password" style="float: right;padding-right: 20px;" target="_blank">忘记密码?</a>
</p>
<input type="hidden" name="action" value="signin">
<p class="fieldset">
<input class="full-width2" type="submit" value="登 录">
</p>
<div class="err-msg"></div>
</div>
</div>
<div id="cd-signup"> <!-- 注册表单 -->
<div class="cd-form">
<p class="fieldset">
<label class="image-replace cd-password" for="verifycode">邀请码</label>
<input class="full-width has-padding has-border" id="signup-verifycode" name="verifycode" type="text" placeholder="输入邀请码">
</p>
<p class="fieldset">
<label class="image-replace cd-username" for="signup-username">用户名</label>
<input class="full-width has-padding has-border" id="signup-username" name="name" type="text" placeholder="输入用户名">
</p>
<p class="fieldset">
<label class="image-replace cd-email" for="signup-email">邮箱</label>
<input class="full-width has-padding has-border" name="email" id="signup-email" type="email" placeholder="输入mail">
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signup-password">密码</label>
<input class="full-width has-padding has-border" id="signup-password" name="password" type="password" placeholder="输入密码">
</p>
<p class="fieldset">
<label class="image-replace cd-password" for="signup-password2">重复输入密码</label>
<input class="full-width has-padding has-border" id="signup-password2" name="password2" type="password" placeholder="重复输入密码">
</p>
<!--
<p class="fieldset">
<input type="checkbox" id="accept-terms">
<label for="accept-terms">我已阅读并同意 <a href="javascript:;">用户协议</a></label>
</p>
-->
<input type="hidden" name="action" value="signup">
<p class="fieldset">
<input class="full-width2" type="submit" value="注册新用户">
</p>
<p class="fieldset">
<a href="//www.runoob.com/w3cnote/runoob-user-test-intro.html#invite" target="_blank">如何获取邀请码?</a>
</p>
<div class="err-msg"></div>
</div>
</div>
<a href="javascript:;" class="cd-close-form">关闭</a>
</div>
</div>
<script src="/wp-content/themes/runoob/assets/js/main.js?v=1.189"></script>
<script src="//static.runoob.com/assets/libs/hl/run_prettify.js"></script>
</body>
</html>
View Code
响应体为HTML格式的文本文件。
4、请求方法
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE ,CONNECT 和PATCH方法。
序号 | 方法 | 描述 |
---|---|---|
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 用于对资源进行部分修改。 |
参考链接:
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/PATCH
- http://www.ruanyifeng.com/blog/2016/08/http.html
- https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#cite_note-21
5、HTTP响应头信息
HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。
在本章节中我们将具体来介绍HTTP响应头信息。
应答头 | 说明 |
---|---|
Allow | 服务器支持哪些请求方法(如GET、POST等)。 |
Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。 |
Content-Length | 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。 |
Content-Type | 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。 |
Date | 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。 |
Expires | 应该在什么时候认为文档已经过期,从而不再缓存它? |
Last-Modified | 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。 |
Location | 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。 |
Refresh | 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。 |
Server | 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。 |
Set-Cookie | 设置和页面关联的Cookie。Servlet不应使用response.setHeader("Set-Cookie", ...),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。 |
WWW-Authenticate | 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。 |
6、HTTP状态码
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
下面是常见的HTTP状态码:
- 200 - 请求成功
- 301 - 资源(网页等)被永久转移到其它URL
- 404 - 请求的资源(网页等)不存在
- 500 - 内部服务器错误
6.1、HTTP状态码分类
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:
分类 | 分类描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
HTTP状态码列表:
状态码 | 状态码英文名称 | 中文描述 |
---|---|---|
100 | Continue | 继续。客户端应继续其请求 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
200 | OK | 请求成功。一般用于GET与POST请求 |
201 | Created | 已创建。成功请求并创建了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
7、HTTP content-type
Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些Asp网页点击的结果却是下载到的一个文件或一张图片的原因。
HTTP content-type 对照表
文件扩展名 | Content-Type(Mime-Type) | 文件扩展名 | Content-Type(Mime-Type) |
---|---|---|---|
.*( 二进制流,不知道下载文件类型) | application/octet-stream | .tif | image/tiff |
.001 | application/x-001 | .301 | application/x-301 |
.323 | text/h323 | .906 | application/x-906 |
.907 | drawing/907 | .a11 | application/x-a11 |
.acp | audio/x-mei-aac | .ai | application/postscript |
.aif | audio/aiff | .aifc | audio/aiff |
.aiff | audio/aiff | .anv | application/x-anv |
.asa | text/asa | .asf | video/x-ms-asf |
.asp | text/asp | .asx | video/x-ms-asf |
.au | audio/basic | .avi | video/avi |
.awf | application/vnd.adobe.workflow | .biz | text/xml |
.bmp | application/x-bmp | .bot | application/x-bot |
.c4t | application/x-c4t | .c90 | application/x-c90 |
.cal | application/x-cals | .cat | application/vnd.ms-pki.seccat |
.cdf | application/x-netcdf | .cdr | application/x-cdr |
.cel | application/x-cel | .cer | application/x-x509-ca-cert |
.cg4 | application/x-g4 | .cgm | application/x-cgm |
.cit | application/x-cit | .class | java/* |
.cml | text/xml | .cmp | application/x-cmp |
.cmx | application/x-cmx | .cot | application/x-cot |
.crl | application/pkix-crl | .crt | application/x-x509-ca-cert |
.csi | application/x-csi | .css | text/css |
.cut | application/x-cut | .dbf | application/x-dbf |
.dbm | application/x-dbm | .dbx | application/x-dbx |
.dcd | text/xml | .dcx | application/x-dcx |
.der | application/x-x509-ca-cert | .dgn | application/x-dgn |
.dib | application/x-dib | .dll | application/x-msdownload |
.doc | application/msword | .dot | application/msword |
.drw | application/x-drw | .dtd | text/xml |
.dwf | Model/vnd.dwf | .dwf | application/x-dwf |
.dwg | application/x-dwg | .dxb | application/x-dxb |
.dxf | application/x-dxf | .edn | application/vnd.adobe.edn |
.emf | application/x-emf | .eml | message/rfc822 |
.ent | text/xml | .epi | application/x-epi |
.eps | application/x-ps | .eps | application/postscript |
.etd | application/x-ebx | .exe | application/x-msdownload |
.fax | image/fax | .fdf | application/vnd.fdf |
.fif | application/fractals | .fo | text/xml |
.frm | application/x-frm | .g4 | application/x-g4 |
.gbr | application/x-gbr | . | application/x- |
.gif | image/gif | .gl2 | application/x-gl2 |
.gp4 | application/x-gp4 | .hgl | application/x-hgl |
.hmr | application/x-hmr | .hpg | application/x-hpgl |
.hpl | application/x-hpl | .hqx | application/mac-binhex40 |
.hrf | application/x-hrf | .hta | application/hta |
.htc | text/x-component | .htm | text/html |
.html | text/html | .htt | text/webviewhtml |
.htx | text/html | .icb | application/x-icb |
.ico | image/x-icon | .ico | application/x-ico |
.iff | application/x-iff | .ig4 | application/x-g4 |
.igs | application/x-igs | .iii | application/x-iphone |
.img | application/x-img | .ins | application/x-internet-signup |
.isp | application/x-internet-signup | .IVF | video/x-ivf |
.java | java/* | .jfif | image/jpeg |
.jpe | image/jpeg | .jpe | application/x-jpe |
.jpeg | image/jpeg | .jpg | image/jpeg |
.jpg | application/x-jpg | .js | application/x-javascript |
.jsp | text/html | .la1 | audio/x-liquid-file |
.lar | application/x-laplayer-reg | .latex | application/x-latex |
.lavs | audio/x-liquid-secure | .lbm | application/x-lbm |
.lmsff | audio/x-la-lms | .ls | application/x-javascript |
.ltr | application/x-ltr | .m1v | video/x-mpeg |
.m2v | video/x-mpeg | .m3u | audio/mpegurl |
.m4e | video/mpeg4 | .mac | application/x-mac |
.man | application/x-troff-man | .math | text/xml |
.mdb | application/msaccess | .mdb | application/x-mdb |
.mfp | application/x-shockwave-flash | .mht | message/rfc822 |
.mhtml | message/rfc822 | .mi | application/x-mi |
.mid | audio/mid | .midi | audio/mid |
.mil | application/x-mil | .mml | text/xml |
.mnd | audio/x-musicnet-download | .mns | audio/x-musicnet-stream |
.mocha | application/x-javascript | .movie | video/x-sgi-movie |
.mp1 | audio/mp1 | .mp2 | audio/mp2 |
.mp2v | video/mpeg | .mp3 | audio/mp3 |
.mp4 | video/mpeg4 | .mpa | video/x-mpg |
.mpd | application/vnd.ms-project | .mpe | video/x-mpeg |
.mpeg | video/mpg | .mpg | video/mpg |
.mpga | audio/rn-mpeg | .mpp | application/vnd.ms-project |
.mps | video/x-mpeg | .mpt | application/vnd.ms-project |
.mpv | video/mpg | .mpv2 | video/mpeg |
.mpw | application/vnd.ms-project | .mpx | application/vnd.ms-project |
.mtx | text/xml | .mxp | application/x-mmxp |
.net | image/pnetvue | .nrf | application/x-nrf |
.nws | message/rfc822 | .odc | text/x-ms-odc |
.out | application/x-out | .p10 | application/pkcs10 |
.p12 | application/x-pkcs12 | .p7b | application/x-pkcs7-certificates |
.p7c | application/pkcs7-mime | .p7m | application/pkcs7-mime |
.p7r | application/x-pkcs7-certreqresp | .p7s | application/pkcs7-signature |
.pc5 | application/x-pc5 | .pci | application/x-pci |
.pcl | application/x-pcl | .pcx | application/x-pcx |
application/pdf | application/pdf | ||
.pdx | application/vnd.adobe.pdx | .pfx | application/x-pkcs12 |
.pgl | application/x-pgl | .pic | application/x-pic |
.pko | application/vnd.ms-pki.pko | .pl | application/x-perl |
.plg | text/html | .pls | audio/scpls |
.plt | application/x-plt | .png | image/png |
.png | application/x-png | .pot | application/vnd.ms-powerpoint |
.ppa | application/vnd.ms-powerpoint | .ppm | application/x-ppm |
.pps | application/vnd.ms-powerpoint | .ppt | application/vnd.ms-powerpoint |
.ppt | application/x-ppt | .pr | application/x-pr |
.prf | application/pics-rules | .prn | application/x-prn |
.prt | application/x-prt | .ps | application/x-ps |
.ps | application/postscript | .ptn | application/x-ptn |
.pwz | application/vnd.ms-powerpoint | .r3t | text/vnd.rn-realtext3d |
.ra | audio/vnd.rn-realaudio | .ram | audio/x-pn-realaudio |
.ras | application/x-ras | .rat | application/rat-file |
.rdf | text/xml | .rec | application/vnd.rn-recording |
.red | application/x-red | .rgb | application/x-rgb |
.rjs | application/vnd.rn-realsystem-rjs | .rjt | application/vnd.rn-realsystem-rjt |
.rlc | application/x-rlc | .rle | application/x-rle |
.rm | application/vnd.rn-realmedia | .rmf | application/vnd.adobe.rmf |
.rmi | audio/mid | .rmj | application/vnd.rn-realsystem-rmj |
.rmm | audio/x-pn-realaudio | .rmp | application/vnd.rn-rn_music_package |
.rms | application/vnd.rn-realmedia-secure | .rmvb | application/vnd.rn-realmedia-vbr |
.rmx | application/vnd.rn-realsystem-rmx | .rnx | application/vnd.rn-realplayer |
.rp | image/vnd.rn-realpix | .rpm | audio/x-pn-realaudio-plugin |
.rsml | application/vnd.rn-rsml | .rt | text/vnd.rn-realtext |
.rtf | application/msword | .rtf | application/x-rtf |
.rv | video/vnd.rn-realvideo | .sam | application/x-sam |
.sat | application/x-sat | .sdp | application/sdp |
.sdw | application/x-sdw | .sit | application/x-stuffit |
.slb | application/x-slb | .sld | application/x-sld |
.slk | drawing/x-slk | .smi | application/smil |
.smil | application/smil | .smk | application/x-smk |
.snd | audio/basic | .sol | text/plain |
.sor | text/plain | .spc | application/x-pkcs7-certificates |
.spl | application/futuresplash | .spp | text/xml |
.ssm | application/streamingmedia | .sst | application/vnd.ms-pki.certstore |
.stl | application/vnd.ms-pki.stl | .stm | text/html |
.sty | application/x-sty | .svg | text/xml |
.swf | application/x-shockwave-flash | .tdf | application/x-tdf |
.tg4 | application/x-tg4 | .tga | application/x-tga |
.tif | image/tiff | .tif | application/x-tif |
.tiff | image/tiff | .tld | text/xml |
.top | drawing/x-top | .torrent | application/x-bittorrent |
.tsd | text/xml | .txt | text/plain |
.uin | application/x-icq | .uls | text/iuls |
.vcf | text/x-vcard | .vda | application/x-vda |
.vdx | application/vnd.visio | .vml | text/xml |
.vpg | application/x-vpeg005 | .vsd | application/vnd.visio |
.vsd | application/x-vsd | .vss | application/vnd.visio |
.vst | application/vnd.visio | .vst | application/x-vst |
.vsw | application/vnd.visio | .vsx | application/vnd.visio |
.vtx | application/vnd.visio | .vxml | text/xml |
.wav | audio/wav | .wax | audio/x-ms-wax |
.wb1 | application/x-wb1 | .wb2 | application/x-wb2 |
.wb3 | application/x-wb3 | .wbmp | image/vnd.wap.wbmp |
.wiz | application/msword | .wk3 | application/x-wk3 |
.wk4 | application/x-wk4 | .wkq | application/x-wkq |
.wks | application/x-wks | .wm | video/x-ms-wm |
.wma | audio/x-ms-wma | .wmd | application/x-ms-wmd |
.wmf | application/x-wmf | .wml | text/vnd.wap.wml |
.wmv | video/x-ms-wmv | .wmx | video/x-ms-wmx |
.wmz | application/x-ms-wmz | .wp6 | application/x-wp6 |
.wpd | application/x-wpd | .wpg | application/x-wpg |
.wpl | application/vnd.ms-wpl | .wq1 | application/x-wq1 |
.wr1 | application/x-wr1 | .wri | application/x-wri |
.wrk | application/x-wrk | .ws | application/x-ws |
.ws2 | application/x-ws | .wsc | text/scriptlet |
.wsdl | text/xml | .wvx | video/x-ms-wvx |
.xdp | application/vnd.adobe.xdp | .xdr | text/xml |
.xfd | application/vnd.adobe.xfd | .xfdf | application/vnd.adobe.xfdf |
.xhtml | text/html | .xls | application/vnd.ms-excel |
.xls | application/x-xls | .xlw | application/x-xlw |
.xml | text/xml | .xpl | audio/scpls |
.xq | text/xml | .xql | text/xml |
.xquery | text/xml | .xsd | text/xml |
.xsl | text/xml | .xslt | text/xml |
.xwd | application/x-xwd | .x_b | application/x-x_b |
.sis | application/vnd.symbian.install | .sisx | application/vnd.symbian.install |
.x_t | application/x-x_t | .ipa | application/vnd.iphone |
.apk | application/vnd.android.package-archive | .xap | application/x-silverlight-app |
HTTP协议
标签:gzip压缩 value play 要求 isp 过期 otl 文件的 电子邮件
======================================================================================
设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。Ted Nelson组织协调万维网协会(World Wide Web Consortium)和互联网工程工作小组(Internet Engineering Task Force )共同合作研究,最终发布了一系列的RFC,其中著名的RFC 2616定义了HTTP 1.1,这也是我们现在最常用的版本,在此之前还存在HTTP 1.0版本以及HTTP 0.9版本
2、URI与URL
问: 为什么要区别URI与URL呢?
答:因为我看书看博客资料都遇到过着两个名词,第一次遇到是在学习API的时候,那时候我是一脸懵逼,不是怎么区分,感觉看过去都是一串网址呀!事实并非如此。
URI:统一资源标示符,只是标识资源在哪里,这意味着存在多个URI可以指向该资源(例如:绝对与相对)【URI包含URL】
URI一般由三部分组成:
1. 访问资源的命名机制。
2. 存放资源的主机名。
3. 资源自身的名称,由路径表示。
语法:[scheme:] scheme-specific-part
URI以scheme和冒号开头。Scheme用大写/小写字母开头,后面为空或者跟着更多的大写/小写字母、数字、加号、减号和点号。冒号把 scheme与scheme-specific-part分开了,并且scheme-specific-part的语法和语义(意思)由URI的名字空间决定。如下面的例子:
http://www.cnn.com,其中http是scheme,//www.cnn.com是 scheme-specific-part,并且它的scheme与scheme-specific-part被冒号分开了。
绝对与相对:
绝对的URI指以scheme(后面跟着冒号)开头的URI。(例如:mailto:jeff@javajeff.com、news:comp.lang.java.help和xyz: //whatever);绝对的URI看作是以某种方式引用某种资源,而这种方式对标识符出现的环境没有依赖。
相对的URI不是以scheme(后面跟着冒号)开始的URI。(例如:articles/articles.html、img/aa.jpg)你可以把相对的URI看作是以某种方式引用某种资源,而这种方式依赖于标识符出现的环境。(即你在html中引用图片:./img/aa.jpg,那么它依赖的就是http)
URL:统一资源定位符,是URI的子集;它除了标识资源的位置,还提供一种定位该资源的主要访问机制(如其网络“位置”)。【即提供具体方式找到该资源(位置+方式)】
URL的格式由下列三部分组成:
1. 第一部分,是协议或称为服务方式 (指定低层使用的协议,例如:http, https, ftp);
2. 第二部分,是存有该资源的主机IP地址(有时也包括端口号);
3. 第三部分,是主机资源的具体地址。如目录和文件名等。
第一部分和第二部分之间用"://"符号隔开,第二部分和第三部分用"/"符号隔开。第一部分和第二部分是不可缺少的,第三部分有时可以省略。
3、TCP握手连接以及断开(扩展)
TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道。引用oneSong所画的一张金典TCP通讯图片
上图中主要分为三部分:建立连接、传输数据、断开连接。
建立连接:
三次握手即可建立TCP连接
1、第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
2、第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
3、第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
为什么需要三次握手呢?
相互确认!(网上有很多解释,这里就不多讲了)
数据传输:
建立好连接后,开始传输数据。TCP数据传输牵涉到的概念很多:超时重传、快速重传、流量控制、拥塞控制等等。(这一切都是为了提供可靠的字节流服务)
断开连接:
四次握手即可断开TCP连接
1、第一次握手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接受数据。
2、第二次握手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
3、第三次握手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
4、第四次握手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
白话文:
1、第一次握手,浏览器对服务器说:“煞笔,我不再给你发数据啦,但可以接受数据。”
2、第二次握手,服务器对浏览器说:“骚货,我知道啦!”
3、第三次握手,服务器对浏览器说:“骚货,我也不再给你发数据啦!”
4、第四次握手,浏览器对服务器说:“煞笔,我知道啦!”
4、特点
HTTP协议永远都是客户端发起请求,服务器回送响应。这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。、
主要特点:
1、支持客户/服务器模式。一旦建立了运输连接(这常常称为建立了会话),浏览器端就向万维网服务器端发送HTTP请求,服务器收到请求后给出HTTP响应。
2、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4、HTTP 0.9和1.0使用非持续连接:限制每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开连接。HTTP 1.1使用持续连接:不必为每个web对象创建一个新的连接,一个连接可以传送多个对象,采用这种方式可以节省传输时间。
5、无状态:HTTP协议是无状态协议。即每一个HTTP请求都是独立的。万维网服务器不保存过去的请求和过去的会话记录。这就是说,同一个用户再次访问同一个服务器时,只要服务器没有进行内容的更新,服务器的响应就给出和以前被访问时相同的响应。服务器不记录曾经访问过的用户,也不记录某个用户访问过多少次。
5、HTTP请求
5.1、Request 消息的结构
请求消息的结构由三部分组成,请求行、请求头、请求主体(即:请求行、消息报头、请求正文。)
【请 求 行】请求方法 空格 请求资源地址(URI、无域名) 空格 HTTP版本 空格 CRLF(换行符)
【请 求 头】标识:内容 CRLF(换行符)
【空 一 行】(表示请求头结束)
【请求主体】(即请求正文,用户的主要数据。POST方式时使用,GET无请求主体)
在HTTP/1.1 协议中,所有的请求头,除Host外,都是可选的。
例:
GET /phpstudy2015-6/ HTTP/1.1
Host: www.cnblogs.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
If-Modified-Since: Sat, 06 May 2017 12:05:41 GMT
5.2、请求方法
HTTP/1.1协议中共定义了八种方法(有时也叫“动作”)来表明Request-URI指定的资源的不同操作方式,最基本的有4种,分别是GET,POST,PUT,DELETE。一个URL地址用于描述一个网络上的资源,而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查,改,增,删4个操作。 我们最常见的就是GET和POST了。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
【我们在浏览器地址栏直接输入地址的时候,采用的就是GET方法】
各方法如下:
1、GET:向特定的资源发出请求
2、POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
3、PUT:向指定资源位置上传其最新内容。
4、DELETE:请求服务器删除Request-URI所标识的资源。
5、HEAD: 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。
6、TRACE:请求服务器会送收到的请求信息,主要用于测试或诊断。
7、OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项和需求
8、CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。(即留为将来使用)
【注意:请求方法区分大小写;所示请求方法应为大写】
GET与POST的区别:
1、GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?postid=6810130&update=1 ;POST方法是把提交的数据放在HTTP包的Body中。
2、GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制。
3、GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
4、GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码。
5.3、http的无状态以及建立连接方式
无状态:
http协议为了保证服务器的内存,不会维持客户端发过来的请求,即同一个客户端的这次请求和上次请求是没有对应关系,对http服务器来说,它并不知道这两个请求来自同一个客户端。例如:一个浏览器在短短几秒之内两次访问同一对象时,服务器进程不会因为已经给它发过应答报文而不接受第二期服务请求。
为了解决这个问题, Web程序引入了Cookie机制来维护状态。
建立连接方式:
HTTP中支持两种连接方式:非持久连接和持久连接(HTTP1.1默认的连接方式为持久连接)。
1、非持久连接方式(采用访问例子来说明)
让我们查看一下非持久连接情况下从服务器到客户传送一个Web页面的步骤。假设该贝面由1个基本HTML文件和10个JPEG图像构成,而且所有这些对象都存放在同一台服务器主机中。再假设该基本HTML文件的URL为:cnblogs.com/phpstudy2015-6/index.html。
下面是具体步骡:
1. HTTP客户初始化一个与服务器主机cnblogs.com中的HTTP服务器的TCP连接。HTTP服务器使用默认端口号80监听来自HTTP客户的连接建立请求。
2. HTTP客户经由与TCP连接相关联的本地套接字发出—个HTTP请求消息。这个消息中包含路径名/somepath/index.html。
3. HTTP服务器经由与TCP连接相关联的本地套接字接收这个请求消息,再从服务器主机的内存或硬盘中取出对象/somepath/index.html,经由同一个套接字发出包含该对象的响应消息。
4. HTTP服务器告知TCP关闭这个TCP连接(不过TCP要到客户收到刚才这个响应消息之后才会真正终止这个连接)。
5. HTTP客户经由同一个套接字接收这个响应消息。TCP连接随后终止。该消息标明所封装的对象是一个HTML文件。客户从中取出这个文件,加以分析后发现其中有10个JPEG对象的引用。
6.给每一个引用到的JPEG对象重复步骡1-4。
上述步骤之所以称为使用非持久连接,原因是每次服务器发出一个对象后,相应的TCP连接就被关闭,也就是说每个连接都没有持续到可用于传送其他对象。每个TCP连接只用于传输一个请求消息和一个响应消息。就上述例子而言,用户每请求一次那个web页面,就产生11个TCP连接。
2、持久连接
非持久连接有一个很大的缺点就是,每一个http请求都需要建立一个TCP连接,就上面的例子而言,get一个html页面就要建立十一次TCP连接,这是严重浪费资源行为!
首先,客户得为每个待请求的对象建立并维护一个新的连接。对于每个这样的连接,TCP得在客户端和服务器端分配TCP缓冲区,并维持TCP变量。对于有可能同时为来自数百个不同客户的请求提供服务的web服务器来说,这会严重增加其负担。其次,如前所述,每个对象都有2个RTT的响应延长——一个RTT用于建立TCP连接,另—个RTT用于请求和接收对象。最后,每个对象都遭受TCP缓启动,因为每个TCP连接都起始于缓启动阶段。不过并行TCP连接的使用能够部分减轻RTT延迟和缓启动延迟的影响。
【RTT(Round-Trip Time): 往返时延。在计算机网络中它是一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延。】
持久连接就能够很好解决这一缺点,在持久连接情况下,服务器在发出响应后让TCP连接继续打开着。同一对客户/服务器之间的后续请求和响应可以通过这个连接发送。整个Web页面(上例中为包含一个基本HTMLL文件和10个图像的页面)自不用说可以通过单个持久TCP连接发送:甚至存放在同一个服务器中的多个web页面也可以通过单个持久TCP连接发送。
通常,HTTP服务器在某个连接闲置一段特定时间后关闭它,而这段时间通常是可以配置的。
持久连接分为不带流水线(without pipelining)和带流水线(with pipelining)两个版本。
不带流水线的版本:
客户只在收到前一个请求的响应后才发出新的请求。这种情况下,web页面所引用的每个对象(上例中的10个图像)都经历1个RTT的延迟,用于请求和接收该对象。与非持久连接2个RTT的延迟相比,不带流水线的持久连接已有所改善,不过带流水线的持久连接还能进一步降低响应延迟。不带流水线版本的另一个缺点是,服务器送出一个对象后开始等待下一个请求,而这个新请求却不能马上到达。这段时间服务器资源便闲置了。
带流水线的持久连接:
HTTP/1.1的默认模式使用带流水线的持久连接。这种情况下,HTTP客户每碰到一个引用就立即发出一个请求,因而HTTP客户可以一个接一个紧挨着发出各个引用对象的请求。服务器收到这些请求后,也可以一个接一个紧挨着发出各个对象。如果所有的请求和响应都是紧挨着发送的,那么所有引用到的对象一共只经历1个RTT的延迟(而不是像不带流水线的版本那样,每个引用到的对象都各有1个RTT的延迟)。另外,带流水线的持久连接中服务器空等请求的时间比较少。与非持久连接相比,持久连接(不论是否带流水线)除降低了1个RTT的响应延迟外,缓启动延迟也比较小。其原因在于既然各个对象使用同一个TCP连接,服务器发出第一个对象后就不必再以一开始的缓慢速率发送后续对象。相反,服务器可以按照第一个对象发送完毕时的速率开始发送下一个对象。
5.4、请求行
正如上面所讲的,请求行以一个方法符号开头,空格之后,一个请求URI,再空格,然后一个HTTP版本,最后一个回车换行。
它的作用是用来说明当前请求的最基本信息。
5.5、请求头
(注:在HTTP/1.1 协议中,所有的请求头,除Host外,都是可选的)
#请求头的书写形式为:Host:coblogs.com rn【标识符:内容 换行】
常见的请求头:
1、Host:(发送请求时,该头域是必需的)主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。
例如: 我们在浏览器中输入:http://www.guet.edu.cn/index.html,浏览器发送的请求消息中,就会包含Host请求头域:Host:http://www.guet.edu.cn,此处使用缺省端口号80,若指定了端口号,则变成:Host:指定端口号。
2、User-Agent:告诉HTTP服务器,客户端使用的操作系统和浏览器的名称和版本。
例如: User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0
3、Content-Type:例如:Content-Type: application/x-www-form-urlencoded
4、Accept-Language:浏览器申明自己接收的语言。语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等;例如:Accept-Language: en-us。如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。
5、Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
6、Accept-Encoding:浏览器申明自己可接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate);Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间。
例如: Accept-Encoding: gzip, deflate。如果请求消息中没有设置这个域,服务器假定客户端对各种内容编码都可以接受。
7、Cookie:最重要的请求头之一, 将cookie的值发送给HTTP服务器。
8、Connection:HTTP 1.1默认进行持久连接keep-alive。
例如:Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。
Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接。
9、Keep-Alive:30保持持久连接30s
10、If-Modified-Since:把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。
例如:If-Modified-Since: Sat, 06 May 2017 12:05:41 GMT
11、If-None-Match:If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag. 使用这样的机制将提高网站的性能。
例如: If-None-Match: "03f2b33c0bfcc1:0"。
12、Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝;在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一样。Pargma只有一个用法, 例如: Pragma: no-cache
13、Cache-Control:指定请求和响应遵循的缓存机制。缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程)。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage。
注意: 在HTTP/1.0版本中,只实现了Pragema:no-cache, 没有实现Cache-Control
Cache-Control:Public 可以被任何缓存所缓存
Cache-Control:Private 内容只缓存到私有缓存中
Cache-Control:no-cache 所有内容都不会被缓存
Cache-Control:no-store 用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
Cache-Control:max-age 指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
Cache-Control:min-fresh 指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
Cache-Control:max-stale 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
14、Accept-Charset:浏览器可接受的字符集。如果在请求消息中没有设置这个域,缺省表示任何字符集都可以接受。
15、Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。
例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
16、Content-Length:表示请求消息正文的长度。例如:Content-Length: 38。
17、From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它。
18、Range:可以请求实体的一个或者多个子范围。
例如:
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)。
5.6、请求主体
请求的主要用户数据,就是POST数据。
如果方式为POST,则需要请求主体部分;GET则没有请求主体
数据形式:类似name=XXX&pwd=XXXX的内容
6、HTTP响应
6.1、Response 消息的结构
响应消息的结构由三部分组成,响应行、相应头、相应主体(即:状态行、消息报头、响应正文。)
【响 应 行】HTTP版本 空格 状态码 空格 状态码的文本描述 空格 CRLF(换行符)
【响 应 头】:内容 CRLF(换行符)
【空 一 行】(表示响应头结束)
【响应主体】所谓响应主体,就是服务器返回的资源的内容。即整个HTML文件。
6.2、响应行
响应数据的第一行,响应结果的概述。
状态码:
状态代码有3位数字组成,状态描述给出了状态代码简短的描述。状态码第一个数字定义了响应的类别,有五种可能取值:
1xx : 指示信息--表示请求已接收,继续处理
2xx : 成功--表示请求已被成功接收、理解、接受
3xx : 重定向--要完成请求必须进行更进一步的操作
4xx : 客户端错误--请求有语法错误或请求无法实现
5xx : 服务器端错误--服务器未能实现合法的请求
所有状态码如下(已折叠):
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本
View Code
6.3、响应头
同理,请求头!
HTTP常见的响应头:
1、Date:表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Sat, 06 May 2017 12:16:56 GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦
2、Content-Type:WEB服务器告诉浏览器自己响应的对象的类型和字符集。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。可在web.xml文件中配置扩展名和MIME类型的对应关系。
例如:
Content-Type: text/html;charset=utf-8
Content-Type:text/html;charset=GB2312
Content-Type: image/jpeg
媒体类型的格式为:大类/小类,比如text/html。
IANA(The Internet Assigned Numbers Authority,互联网数字分配机构)定义了8个大类的媒体类型,分别是:
application— (比如: application/vnd.ms-excel.)
audio (比如: audio/mpeg.)
image (比如: image/png.)
message (比如,:message/http.)
model(比如:model/vrml.)
multipart (比如:multipart/form-data.)
text(比如:text/html.)
video(比如:video/quicktime.)
3、Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它,重新从服务器获取,会更新缓存。过期之前使用本地缓存。HTTP1.1的客户端和缓存会将非法的日期格式(包括0)看作已经过期。
eg:为了让浏览器不要缓存页面,我们也可以将Expires实体报头域,设置为0。
例如: Expires: Tue, 08 Feb 2022 11:35:14 GMT
4、P3P:用于跨域设置Cookie, 这样可以解决iframe跨域访问cookie的问题
例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
5、Set-Cookie:非常重要的header, 用于把cookie发送到客户端浏览器,每一个写入cookie都会生成一个Set-Cookie。
例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com
6、ETag:和If-None-Match 配合使用。
7、Last-Modified:用于指示资源的最后修改日期和时间。Last-Modified也可用setDateHeader方法来设置。
8、Content-Range:用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-length。
例如,传送头500个字节次字段的形式:Content-Range:bytes0-499/1234如果一个http消息包含此节(例如,对范围请求的响 应或对一系列范围的重叠请求),Content-Range表示传送的范围。
9、Content-Length:指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的过程中,Content-Length的方式要预先在服务器中缓存所有数据,然后所有数据再一股脑儿地发给客户端。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入ByteArrayOutputStram,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。
例如: Content-Length: 19847
10、Content-Encoding:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
例如:Content-Encoding:gzip
11、Content-Language:WEB服务器告诉浏览器自己响应的对象所用的自然语言。
例如: Content-Language:da。没有设置该域则认为实体内容将提供给所有的语言阅读。
12、Server:指明HTTP服务器用来处理请求的软件信息。例如:Server: Microsoft-IIS/7.5、Server:Apache-Coyote/1.1。此域能包含多个产品标识和注释,产品标识一般按照重要性排序
13、X-AspNet-Version:如果网站是用ASP.NET开发的,这个header用来表示ASP.NET的版本。
例如: X-AspNet-Version: 4.0.30319
14、X-Powered-By:表示网站是用什么技术开发的。
例如: X-Powered-By: ASP.NET
15、Connection:keep-alive /close
16、Location:用于重定向一个新的位置,包含新的URL地址。表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。Location响应报头域常用在更换域名的时候。
17、Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。注意Refresh的意义是“N秒之后刷新本页面或访问指定页面”,而不是“每隔N秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。
6.4、响应主体
就是服务器返回的资源的内容。即整个HTML文件
7、HTTP请求详细过程
从前面讲解中我们大概对HTTP有了一个基本的认识,那么接下来我们就详细研究了解HTTP请求的具体过程。
引用咸鱼老弟的博客文章
7.1、 输入地址
当我们开始在浏览器中输入网址的时候,浏览器其实就已经在智能的匹配可能得 url 了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url,然后给出智能提示,让你可以补全url地址。对于 google的chrome 的浏览器,他甚至会直接从缓存中把网页展示出来,就是说,你还没有按下 enter,页面就出来了。
7.2、浏览器查找域名的IP
1、请求一旦发起,浏览器首先要做的事情就是解析这个域名,一般来说,浏览器会首先查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,如果有的话就直接使用 hosts 文件里面的 ip 地址。
2、如果在本地的 hosts 文件没有能够找到对应的 ip 地址,浏览器会发出一个 DNS请求到本地DNS服务器 。本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。
3、查询你输入的网址的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,本地DNS服务器还要向DNS根服务器进行查询。
4、根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。这种过程是迭代的过程。
5、本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。
6、最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
下面这张图很完美的解释了这一过程:
知识扩展:
1)什么是DNS?
DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。
通俗的讲,我们更习惯于记住一个网站的名字,比如www.baidu.com,而不是记住它的ip地址,比如:167.23.10.2。而计算机更擅长记住网站的ip地址,而不是像www.baidu.com等链接。因为,DNS就相当于一个电话本,比如你要找www.baidu.com这个域名,那我翻一翻我的电话本,我就知道,哦,它的电话(ip)是167.23.10.2。
2)DNS查询的两种方式:递归查询和迭代查询
1、递归解析
当局部DNS服务器自己不能回答客户机的DNS查询时,它就需要向其他DNS服务器进行查询。此时有两种方式,如图所示的是递归方式。局部DNS服务器自己负责向其他DNS服务器进行查询,一般是先向该域名的根域服务器查询,再由根域名服务器一级级向下查询。最后得到的查询结果返回给局部DNS服务器,再由局部DNS服务器返回给客户端。
简单来讲,就是参与此次寻找IP的所有服务器,最后都能够得到该域名对应的IP信息(将信息进行往返传送!)
2、迭代解析
当局部DNS服务器自己不能回答客户机的DNS查询时,也可以通过迭代查询的方式进行解析,如图所示。局部DNS服务器不是自己向其他DNS服务器进行查询,而是把能解析该域名的其他DNS服务器的IP地址返回给客户端DNS程序,客户端DNS程序再继续向这些DNS服务器进行查询,直到得到查询结果为止。也就是说,迭代解析只是帮你找到相关的服务器而已,而不会帮你去查。比如说:baidu.com的服务器ip地址在192.168.4.5这里,你自己去查吧,本人比较忙,只能帮你到这里了。
简单的来讲,就是只有最后一台服务器与最初的服务器进行该域名/IP信息的传送!
3)DNS域名称空间的组织方式
我们在前面有说到根DNS服务器,域DNS服务器,这些都是DNS域名称空间的组织方式。按其功能命名空间中用来描述 DNS 域名称的五个类别的介绍详见下表中,以及与每个名称类型的示例
4)DNS负载均衡
当一个网站有足够多的用户的时候,假如每次请求的资源都位于同一台机器上面,那么这台机器随时可能会蹦掉。处理办法就是用DNS负载均衡技术,它的原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的?例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等。
7.3、浏览器携带IP地址向Web服务器发起HTTP请求
拿到域名对应的IP地址之后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有httpd,nginx等)80端口发起TCP的连接请求。
这个连接请求到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。
TCP连接参考上面
建立了TCP连接之后,发起一个http请求。一个典型的 http request header 一般需要包括请求的方法,例如 GET 或者 POST 等,不常用的还有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的浏览器只能发起 GET 或者 POST 请求。
7.4、服务器的永久重定向响应
服务器给浏览器响应一个301永久重定向响应,这样浏览器就会访问“http://www.google.com/” 而非“http://google.com/”。
为什么服务器一定要重定向而不是直接发送用户想看的网页内容呢?其中一个原因跟搜索引擎排名有关。如果一个页面有两个地址,就像http://www.yy.com/和http://yy.com/,搜索引擎会认为它们是两个网站,结果造成每个搜索链接都减少从而降低排名。而搜索引擎知道301永久重定向是什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。还有就是用不同的地址会造成缓存友好性变差,当一个页面有好几个名字时,它可能会在缓存里出现好几次。
扩展知识
1)301和302的区别。
301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。
他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;
302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于301
2)重定向原因:
(1)网站调整(如改变网页目录结构);
(2)网页被移到一个新地址;
(3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。
这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。
3)什么时候进行301或者302跳转呢?
当一个网站或者网页24—48小时内临时移动到一个新的位置,这时候就要进行302跳转,而使用301跳转的场景就是之前的网站因为某种原因需要移除掉,然后要到新的地址访问,是永久性的。
清晰明确而言:使用301跳转的大概场景如下:
1、域名到期不想续费(或者发现了更适合网站的域名),想换个域名。
2、在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。
3、空间服务器不稳定,换空间的时候。
7.5、发出新的请求(重定向)
现在浏览器知道了 "http://www.google.com/"才是要访问的正确地址,所以它会发送另一个http请求。重复上面的http请求步骤
7.6、服务器主机处理
经过前面的重重步骤,我们终于将我们的http请求发送到了服务器这里,其实前面的重定向已经是到达服务器了,那么,服务器是如何处理我们的请求的呢?
后端从在固定的端口接收到TCP报文开始,它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。
【一些大一点的网站会将你的请求到反向代理服务器中,因为当网站访问量非常大,网站越来越慢,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。此时,客户端不是直接通过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,然后将结果返回给客户端,这里Nginx的作用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。】
7.7、Web应用服务器处理http请求
【假设服务器端使用nginx+php(fastcgi)架构提供服务】
假设我此时输入的URL为http://www.mecnblogs.com/
① nginx读取配置文件,并寻找文件
当服务器主机将浏览器发送过来的所有数据通过各个网络层的相应协议的规定进行了解密以及封装,最后将数据包送达应用层使用。(可参考TCP/IP网络模型)
当Nginx在收到浏览器 GET / 请求时,会读取http请求里面的头部信息,根据Host来匹配 自己的所有的虚拟主机的配置文件的server_name,看看有没有匹配的,有匹配那么就读取该虚拟主机的配置,发现如下配置:
root /web/echo
通过这个就知道所有网页文件的就在这个目录下 这个目录就是/ 当我们http://www.mecnblogs.com/时就是访问这个目录下面的文件,例如访问http://www.mecnblogs.com/index.html,那么代表/web/echo下面有个文件叫index.html
index index.html index.htm index.php
通过这个就能得知网站的首页文件是那个文件,也就是我们在入http://www.mecnblogs.com/ ,nginx就会自动帮我们把index.html(假设首页是index.php 当然是会尝试的去找到该文件,如果没有找到该文件就依次往下找,如果这3个文件都没有找到,那么就抛出一个404错误)加到后面,那么添加之后的URL是/index.php,然后根据后面的配置进行处理
location ~ .*.php(/.*)*$ {
root /web/echo;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
astcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
这一段配置指明凡是请求的URL中匹配(这里是启用了正则表达式进行匹配) *.php后缀的(后面跟的参数)都交给后端的fastcgi进程进行处理。
② 把php文件交给fastcgi进程去处理
于是nginx把/index.php这个URL交给了后端的fastcgi进程处理,等待fastcgi处理完成后(结合数据库查询出数据,填充模板生成html文件)返回给nginx一个index.html文档,Nginx再把这个index.html返回给浏览器(通过HTTP协议返回,即HTTP响应【响应消息结构可以参考上面】),于是乎浏览器就拿到了首页的html代码,同时nginx写一条访问日志到日志文件中去。
【扩展:】
nginx是怎么找index.php文件的?
当nginx发现需要/web/echo/index.php文件时,就会向内核发起IO系统调用(因为要跟硬件打交道,这里的硬件是指硬盘,通常需要靠内核来操作,而内核提供的这些功能是通过系统调用来实现的),告诉内核,我需要这个文件,内核从/开始找到web目录,再在web目录下找到echo目录,最后在echo目录下找到index.php文件,于是把这个index.php从硬盘上读取到内核自身的内存空间,然后再把这个文件复制到nginx进程所在的内存空间,于是乎nginx就得到了自己想要的文件了。
寻找文件在文件系统层面是怎么操作的?
比如nginx需要得到/web/echo/index.php这个文件
每个分区(像ext3 ext3等文件系统,block块是文件存储的最小单元 默认是4096字节)都是包含元数据区和数据区,每一个文件在元数据区都有元数据条目(一般是128字节大小),每一个条目都有一个编号,我们称之为inode(index node 索引节点),这个inode里面包含 文件类型、权限、连接次数、属主和数组的ID、时间戳、这个文件占据了那些磁盘块也就是块的编号(block,每个文件可以占用多个block,并且block不一定是连续的,每个block是有编号的),如下图所示:
还有一个要点:目录其实也普通是文件,也需要占用磁盘块,目录不是一个容器。你看默认创建的目录就是4096字节,也就说只需要占用一个磁盘块,但这是不确定的。所以要找到目录也是需要到元数据区里面找到对应的条目,只有找到对应的inode就可找到目录所占用的磁盘块。
那到底目录里面存放着什么,难道不是文件或者其他目录吗?
其实目录存着这么一张表(姑且这么理解),里面放着 目录或者文件的名称和对应的inode号(暂时称之为映射表),如下图:
假设
/ 在数据区占据 1、2号block ,/其实也是一个目录 里面有3个目录 web 111
web 占据 5号block 是目录 里面有2个目录 echo data
echo 占据 11号 block 是目录 里面有1个文件 index.php
index.php 占据 15 16号 block 是文件
其在文件系统中分布如下图所示:
那么内核究竟是怎么找到index.php这个文件的呢?
内核拿到nginx的IO系统调用要获取/web/echo/index.php这个文件请求之后
① 内核读取元数据区 / 的inode,从inode里面读取/所对应的数据块的编号,然后在数据区找到其对应的块(1 2号块),读取1号块上的映射表找到web这个名称在元数据区对应的inode号
② 内核读取web对应的inode(3号),从中得知web在数据区对应的块是5号块,于是到数据区找到5号块,从中读取映射表,知道echo对应的inode是5号,于是到元数据区找到5号inode
③ 内核读取5号inode,得到echo在数据区对应的是11号块,于是到数据区读取11号块得到映射表,得到index.php对应的inode是9号
④ 内核到元数据区读取9号inode,得到index.php对应的是15和16号数据块,于是就到数据区域找到15 16号块,读取其中的内容,得到index.php的完整内容
7.8、浏览器处理并显示html文件
在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了,浏览器是如何把页面呈现在屏幕上的呢?不同浏览器可能解析的过程不太一样,这里我们只介绍webkit的渲染过程,下图对应的就是WebKit渲染的过程,这个过程包括:
解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树
在浏览器显示的时候,当遇到要获取外图片,CSS,JS文件等等时,浏览器将会发起不断发起异步的http请求来获取这些资源。
最后
以上就是幽默百褶裙为你收集整理的http 分析的全部内容,希望文章能够帮你解决http 分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复