HTTP(Hypertest Transfer Protocol)是用于传输像HTML这样的超文本文件的应用层协议。它被设计用于WEB浏览器端和WEB服务端的交互,但也有其它用途。HTTP遵循经典的client-server模型,客户端发起请求尝试建立连接,然后等待服务端的应答。HTTP是无状态协议,这意味着服务端在两次请求间不会记录任何状态。
2.1请求URL
每个请求有一个请求URL。
2.2请求方法[2]:
HTTP定义了一系列请求方法,这些方法表明要对给定资源所做的操作。HTTP请求方法包含GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH等8中类型。
2.3应答状态码[3]
HTTP应答状态码表名一个HTTP请求是否成功完成。应答状态码被分为5类:
信息应答(100
– 199
)
成功应答(200
– 299
)
重定向信息(300
– 399
)
客户端错误(400
– 499
)
服务端错误(500
– 599
)
2.4 HTTP头[4]
HTTP头使得客户端和服务端之间可以通过HTTP请求和应答传递信息。HTTP头包含大小写敏感的名称,后面跟一个“:”,然后是http头的值。HTTP的值前面的空格会被忽略。
2.4.1 Authentication
2.4.2 Cookies
2.4.3 CORS
2.5 请求体[6]
请求体(body)是Request接口的一个属性,它是包含请求体内容的可读流。GET和HEAD请求不能携带请求体,如果携带请求体会返回null。
Demo1发起了一个POST类型的请求,在Chrome的开发者工具中可以看到请求URL、请求方法、应答状态码、HTTP头和请求体等信息,如图1。
Copy
var xhttp = new XMLHttpRequest(); xhttp.open("POST", "http://localhost:8080/day05_lzs/", true); xhttp.send("fname=Bill&lname=Gates");
Demo1. 使用XMLHttpRequest发起一个简单的POST请求
图1. Chrome浏览器中使用XMLHttpRequest发起的一个简单的POST请求的请求信息
3.1 document类型的请求
如图2,从Chrome浏览器的开发者工具可以看出,请求的类型分为Fetch/XHR、JS、CSS、Img、Media、Font、Doc、WS (WebSocket)、 Wasm (WebAssembly)、Manifest和Other(不属于前面列出类型中的一种)。通过浏览器地址栏发起的请求和form表单请求的类型都是document。
图2. Chrome浏览器开发者工具中请求的几种类型
3.1.1 通过浏览器地址栏发起的请求
当我们访问一个web页面时,在浏览器地址栏输入访问的地址并确认后,会发起document类型的请求,如图3。
图3. 使用Chrome浏览器在地址栏发起的document类型的请求
3.1.2 Form请求
Demo2是一个form表单。当form表单提交时,会发送一个document类型的请求,如图4。
Copy
Demo2. 一个form表单的HTML代码
图4. 使用Chrome浏览器form表单提交时发起document类型的请求
3.2 XHR请求
3.2.1 XMLHttpRequest简介
XMLHttpRequest(XHR) 对象用于和服务端交互。它可以从URL取回数据而不用刷新整个页面,这使得可以只更新页面的局部而不影响整个页面。[7]
如Demo3所示,使用XMLHttpRequest发送GET请求,在URL中添加“?fname=Bill&lname=Gates”实现发送信息。XMLHttpResponse 对象的 onreadystatechange
属性中定义了请求接收到应答是所执行的操作。该GET请求的在浏览器中的请求信息如图5所示。
Copy
//GET请求 var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { console.log("请求成功回调") } }; xhttp.open("GET", "http://localhost:8080/day05_lzs/?fname=Bill&lname=Gates", true); xhttp.send();
Demo3. 使用XMLHttpRequest发送GET请求
图5. 使用XMLHttpRequest发送GET请求
3.2.2 使用XMLHttpRequest发送post请求的4种方式
如Demo3所示,使用XMLHttpRequest发送POST请求,发送数据的方式有4种[8]。4中POST请求在浏览器中的请求信息如图6-9所示,他们具有不同的请求头content_type,请求体的格式分为“Request Load”和“Form Data”两种。
Copy
//POST请求,发送数据方式一 var xhttp = new XMLHttpRequest(); xhttp.open("POST", "http://localhost:8080/day05_lzs/", true); xhttp.send("fname=Bill&lname=Gates"); //POST请求,发送数据方式二 var xhttp = new XMLHttpRequest(); xhttp.open("POST", "http://localhost:8080/day05_lzs/", true); xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhttp.send("fname=Bill&lname=Gates"); //POST请求,发送数据方式三 var xhttp = new XMLHttpRequest(); const formData = new FormData(); formData.append("fname", "Bill"); formData.append("lname", "Gates"); xhttp.open("POST", "http://localhost:8080/day05_lzs/", true); xhttp.send(formData); //POST请求,发送数据方式四 var xhttp = new XMLHttpRequest(); xhttp.open("POST", "http://localhost:8080/day05_lzs/", true); xhttp.setRequestHeader("Content-type", "application/json"); xhttp.send('{"fname":"Bill","lname":"Gates"}');
Demo3. 使用XMLHttpRequest发送POST请求时发送数据的四种方式
(https://img2023.cnblogs.com/blog/1389306/202306/1389306-20230610223139651-880342569.png)
图6. 使用XMLHttpRequest发送POST请求时发送数据方式一
图7.使用XMLHttpRequest发送POST请求时发送数据方式二
图8.使用XMLHttpRequest发送POST请求时发送数据方式三
图9. 使用XMLHttpRequest发送POST请求时发送数据方式四
3.2.3 JQuery.AJAX()简介[9]
AJAX 组合了XMLHttpRequest 对象、JavaScript 和 HTML DOM;XMLHttpRequest 对象用于从 web 服务器请求数据,JavaScript 和 HTML DOM用于显示或使用数据。不同的浏览器对于AJAX的使用方式可能有所不同,JQUERY中解决了这个问题。在JQUERY使用ajax只需一行代码。
Copy
//方式一 $.ajax({ url: "redirectTest",method:"GET",async:true, success: function(){ console.log("ajax请求成功回调") }}); //方式二 $.get("redirectTest",function(){console.log("ajax请求成功回调")});
Demo4. JQuery中发送ajax请求的2中方式
3.2.4 AJAX请求跨域时的浏览器策略
为了减少跨域请求的风险(比如csrf),浏览器对从脚本中发起的跨域HTTP请求有严格限制。比如,XMLHttpRequest和Fetch这两个API都遵循同源策略(same-origin policy),而对form表单提交的、浏览器地址栏发起的、HTML重定向和JavaScript重定向(详见3.4.2和3.4.3节)等document类型的请求则没有限制。同源策略是指,浏览器只能加载相同初始域名(origin domain)的应答,如果要加载其它域名的应答,应答头中必须包含必要的CORS头,比如“Access-Control-Allow-Origin”[10]。如Demo5,由初始域名为localhost:8080向目标域名为127.0.0.1:8080发送ajax请求时,浏览器会报出如图10的“CORS error”错误,错误的详细信息如图11。可以通过在CORSFilter对应答进行拦截(如Demo6),设置应答头”Access-Control-Allow-Origin:*“,再次发送跨域请求,浏览器不再报出”CORS error“的错误。
Copy
//这是localhost:8080/day05_lzs请求响应的index.html页面,即初始域名为localhost:8080 var xhttp = new XMLHttpRequest(); //向目标域名127.0.0.1:8080发送跨域请求 xhttp.open("GET", "http://127.0.0.1:8080/day05_lzs/?fname=Bill&lname=Gates", true); xhttp.send();
Demo5. 初始域名为localhost:8080,向目标域名为127.0.0.1:8080发送ajax请求
图10. 跨域发送ajax请求时,浏览器报出“CORS error”
图11. 跨域发送ajax请求时,浏览器控制台输出的详细错误信息
Copy
public class CORSFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //允许所有的初始域名(origin domain)加载该应答 rep.setHeader("Access-Control-Allow-Origin","*"); } }
Demo6. 设置应答头"Access-Control-Allow-Origin",已解决跨域问题