概念wiki
超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。
协议概述
HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)。我们称这个客户端为用户代理程序(user agent)。应答的服务器上存储着一些资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(origin server)。在用户代理和源服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel)。
尽管TCP/IP协议是互联网上最流行的应用,HTTP协议中,并没有规定必须使用它或它支持的层。事实上,HTTP可以在任何互联网协议上,或其他网络上实现。HTTP假定其下层协议提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用。因此也就是其在TCP/IP协议族使用TCP作为其传输层。
通常,由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端的请求。一旦收到请求,服务器会向客户端返回一个状态,比如"HTTP/1.1 200 OK",以及返回的内容,如请求的文件、错误消息、或者其它信息。
请求方法
GET
向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中
HEAD
与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)
POST
向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
PUT
向指定资源位置上传其最新内容
DELETE
请求服务器删除Request-URI所标识的资源
TRACE
回显服务器收到的请求,主要用于测试或诊断。
OPTIONS
这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用"*"来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作
CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)
状态码说明
所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。
状态代码的第一个数字代表当前响应的类型:
- 1xx消息——请求已被服务器接收,继续处理
- 2xx成功——请求已成功被服务器接收、理解、并接受
- 3xx重定向——需要后续操作才能完成这一请求
- 4xx请求错误——请求含有词法错误或者无法被执行
- 5xx服务器错误——服务器在处理某个正确请求时发生错误
常见的有
- 200 OK
- 400 Bad Request常见的语法错误等
- 401 Unauthorized 类似403
- 403 Forbidden
- 404 Not Found
- 405 Method Not Allowed
- 500 Internal Server Error通用错误
- 502 Bad Gateway
HTTP 报文MDN
有两种HTTP报文的类型,请求与响应,每种都有其特定的格式
请求
请求由以下元素组成:
- 一个HTTP的method,经常是由一个动词像GET, POST 或者一个名词像OPTIONS,HEAD来定义客户端的动作行为。通常客户端的操作都是获取资源(GET方法)或者发送HTML form表单值(POST方法),虽然在一些情况下也会有其他操作。
- 要获取的资源的路径,通常是上下文中就很明显的元素资源的URL,它没有protocol (http://),domain(developer.mozilla.org),或是TCP的port(HTTP一般在80端口)。
- HTTP协议版本号。
- 为服务端表达其他信息的可选头部headers。
-
对于一些像POST这样的方法,报文的body就包含了发送的资源,这与响应报文的body类似。
响应
响应报文包含了下面的元素:
- HTTP协议版本号。
- 一个状态码(status code),来告知对应请求执行成功或失败,以及失败的原因。
- 一个状态信息,这个信息是非权威的状态码描述信息,可以由服务端自行设定。
- HTTP headers,与请求头部类似。
-
可选项,比起请求报文,响应报文中更常见地包含获取的资源body。
常见问题
同源与跨域CORS 同源参考 跨域参考
概念
同源设计目的是为了保证数据安全,防止恶意代码获取数据。
同源必须满足三个方面:
- 协议相同
- 域名相同
- 端口相同(默认端口是80,可以省略)
如果是非同源的,以下行为会受到限制:
- Cookie、LocalStorage和IndexDB无法读取
- DOM无法获取
- AJAX请求不能发送
AJAX请求不能发送
解决ajax问题
jsonp
由两部分组成:回调函数和数据。其基本思路是:动态插入script标签,向服务器请求json数据,返回的数据将在回调函数里获得,服务器需要添加callback函数处理,缺点是只支持GET请求。
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
// 定义回调函数
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
WebScoket
CORS
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
相比jsonp只能发送get请求,CORS允许发送任何类型的请求。但CORS要求浏览器和服务器同时支持。目前所有浏览器都支持,IE需要IE10以上。
整个CORS通讯过程中都是浏览器自动完成,不需要用户的参与。CORS通讯和同源的AJAX请求没有区别。浏览器一旦发现AJAX请求跨域,就会自动添加一些头部信息,有时候还会多出一次附加请求。实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
浏览器将CORS请求分为两类:简单请求和非简单请求
某些请求不会触发 CORS 预检请求。若请求满足所有下述条件,则该请求可视为“简单请求”:
+ 使用下列方法之一:
- GET
- HEAD
- POST
+ Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
当请求满足下述任一条件时,即应首先发送预检请求:
+ 使用了下面任一 HTTP 方法:
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
- Content-Type 的值不是下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
对于简单请求,浏览器会自动在头部信息里增加一个Origin字段,用来表示请求来自与哪个源,服务器根据这个值决定是否同意此次请求。如果Origin不在请求范围内,服务器返回一个正常的http回应。这个回应的头信息中没有Access-Control-Allow-Origin字段,浏览器发现没有这个字段之后就会抛出一个错误。如果Origin在请求范围内,服务器返回的响应会多出几个头信息字段,其中一个是Access-Control-Allow-Origin,它的值要么是Origin的值,要么是\*,表示允许任何域名的请求。
对于非简单请求,它会在正式通信之前,增加一次http查询请求,称为"预检"请求(preflight)。通常是一个OPTION请求。这个请求先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪http动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
- 设置代理服务器,用代理服务器代替网页直接发起请求规避跨域