1 前端数据请求方式
2 Http协议的解析
3 XHR的基本用法
4 XHR的进阶和封装
5 Fetch的使用详解
6 前端文件上传流程
早期的页面都是后端做好,浏览器直接拿到页面展示的,用到的是jsp、asp、php等等的语言。 这个叫做服务器端渲染SSR。
这里后端向前端发送数据,数据结果前端渲染页面,这个叫做 客户端渲染。
FeHelper插件的演练
1
const banners = { "banner": { "context": { "currentTime": 1538014774 }, "isEnd": true, "list": [ { "acm": "3.mce.2_10_1jhwa.43542.0.ccy5br4OlfK0Q.pos_0-m_454801-sd_119", "height": 390, "height923": 390, "image": "https://s10.mogucdn.com/mlcdn/c45406/180926_45fkj8ifdj4l824l42dgf9hd0h495_750x390.jpg", "image923": "https://s10.mogucdn.com/mlcdn/c45406/180926_7d5c521e0aa3h38786lkakebkjlh8_750x390.jpg", "link": "https://act.mogujie.com/huanxin0001?acm=3.mce.2_10_1jhwa.43542.0.ccy5br4OlfK0Q.pos_0-m_454801-sd_119", "title": "焕新女装节", "width": 750, "width923": 750 }, { "acm": "3.mce.2_10_1ji16.43542.0.ccy5br4OlfK0R.pos_1-m_454889-sd_119", "height": 390, "height923": 390, "image": "https://s10.mogucdn.com/mlcdn/c45406/180926_31eb9h75jc217k7iej24i2dd0jba3_750x390.jpg", "image923": "https://s10.mogucdn.com/mlcdn/c45406/180926_14l41d2ekghbeh771g3ghgll54224_750x390.jpg", "link": "https://act.mogujie.com/ruqiu00001?acm=3.mce.2_10_1ji16.43542.0.ccy5br4OlfK0R.pos_1-m_454889-sd_119", "title": "入秋穿搭指南", "width": 750, "width923": 750 }, { "acm": "3.mce.2_10_1jfj8.43542.0.ccy5br4OlfK0S.pos_2-m_453270-sd_119", "height": 390, "height923": 390, "image": "https://s10.mogucdn.com/mlcdn/c45406/180919_3f62ijgkj656k2lj03dh0di4iflea_750x390.jpg", "image923": "https://s10.mogucdn.com/mlcdn/c45406/180919_47iclhel8f4ld06hid21he98i93fc_750x390.jpg", "link": "https://act.mogujie.com/huanji001?acm=3.mce.2_10_1jfj8.43542.0.ccy5br4OlfK0S.pos_2-m_453270-sd_119", "title": "秋季护肤大作战", "width": 750, "width923": 750 }, { "acm": "3.mce.2_10_1jepe.43542.0.ccy5br4OlfK0T.pos_3-m_452733-sd_119", "height": 390, "height923": 390, "image": "https://s10.mogucdn.com/mlcdn/c45406/180917_18l981g6clk33fbl3833ja357aaa0_750x390.jpg", "image923": "https://s10.mogucdn.com/mlcdn/c45406/180917_0hgle1e2c350a57ekhbj4f10a6b03_750x390.jpg", "link": "https://act.mogujie.com/liuxing00001?acm=3.mce.2_10_1jepe.43542.0.ccy5br4OlfK0T.pos_3-m_452733-sd_119", "title": "流行抢先一步", "width": 750, "width923": 750 } ], "nextPage": 1 } }
XHR-XHR请求的基本使用
1
// 1.创建XMLHttpRequest对象 const xhr = new XMLHttpRequest() // 2.监听状态的改变(宏任务) xhr.onreadystatechange = function() { // console.log(xhr.response) if (xhr.readyState !== XMLHttpRequest.DONE) return // 将字符串转成JSON对象(js对象) const resJSON = JSON.parse(xhr.response) const banners = resJSON.data.banner.list console.log(banners) } // 3.配置请求open // method: 请求的方式(get/post/delete/put/patch...) // url: 请求的地址 xhr.open("get", "http://123.207.32.32:8000/home/multidata") // 4.发送请求(浏览器帮助发送对应请求) xhr.send()
XHR-XHR状态变化的监听
这里发送的是异步请求,并且可以拿到状态码,4种状态码对应不同的事件。
// 1.创建XMLHttpRequest对象 const xhr = new XMLHttpRequest() // 2.监听状态的改变(宏任务) // 监听四种状态 xhr.onreadystatechange = function() { // 1.如果状态不是DONE状态, 直接返回 if (xhr.readyState !== XMLHttpRequest.DONE) return // 2.确定拿到了数据 console.log(xhr.response) } // 3.配置请求open xhr.open("get", "http://123.207.32.32:8000/home/multidata") // 4.发送请求(浏览器帮助发送对应请求) xhr.send()
XHR-XHR发送同步的请求
open的第三个参数可以设置是否是异步请求,设置false就是改变成同步请求,只有服务器返回浏览器有接过来才会执行后续的代码。
// 1.创建XMLHttpRequest对象 const xhr = new XMLHttpRequest() // 2.监听状态的改变(宏任务) // 监听四种状态 // xhr.onreadystatechange = function() { // // 1.如果状态不是DONE状态, 直接返回 // if (xhr.readyState !== XMLHttpRequest.DONE) return // // 2.确定拿到了数据 // console.log(xhr.response) // } // 3.配置请求open // async: false // 实际开发中要使用异步请求, 异步请求不会阻塞js代码继续执行 xhr.open("get", "http://123.207.32.32:8000/home/multidata", false) // 4.发送请求(浏览器帮助发送对应请求) xhr.send() // 5.同步必须等到有结果后, 才会继续执行 console.log(xhr.response) console.log("------") console.log("++++++") console.log("******")
XHR-XHR其他事件的监听
函数的调用方式不同。
const xhr = new XMLHttpRequest() // onload监听数据加载完成 xhr.onload = function() { console.log("onload") } xhr.open("get", "http://123.207.32.32:8000/home/multidata") xhr.send()
XHR-XHR响应数据和类型
告知xhr获取到的数据的类型
xhr.responseType = "json"// 1. const xhr = new XMLHttpRequest() // 2.onload监听数据加载完成 xhr.onload = function() { // const resJSON = JSON.parse(xhr.response) console.log(xhr.response) // console.log(xhr.responseText) // console.log(xhr.responseXML) } // 3.告知xhr获取到的数据的类型 xhr.responseType = "json" // xhr.responseType = "xml" // 4.配置网络请求 // 4.1.json类型的接口 xhr.open("get", "http://123.207.32.32:8000/home/multidata") // 4.2.json类型的接口 // xhr.open("get", "http://123.207.32.32:1888/01_basic/hello_json") // 4.3.text类型的接口 // xhr.open("get", "http://123.207.32.32:1888/01_basic/hello_text") // 4.4.xml类型的接口 // xhr.open("get", "http://123.207.32.32:1888/01_basic/hello_xml") // 5.发送网络请求 xhr.send()
XHR-获取HTTP的状态码
xhr.status
// 1.创建对象 const xhr = new XMLHttpRequest() // 2.监听结果 xhr.onload = function() { console.log(xhr.status, xhr.statusText) // 根据http的状态码判断是否请求成功 if (xhr.status >= 200 && xhr.status < 300) { console.log(xhr.response) } else { console.log(xhr.status, xhr.statusText) } } xhr.onerror = function() { console.log("onerror", xhr.status, xhr.statusText) } // 3.设置响应类型 xhr.responseType = "json" // 4.配置网络请求 // xhr.open("get", "http://123.207.32.32:8000/abc/cba/aaa") xhr.open("get", "http://123.207.32.32:8000/home/multidata") // 5.发送网络请求 xhr.send()
XHR-GET-POST请求传参
1
const formEl = document.querySelector(".info") const sendBtn = document.querySelector(".send") sendBtn.onclick = function() { // 创建xhr对象 const xhr = new XMLHttpRequest() // 监听数据响应 xhr.onload = function() { console.log(xhr.response) } // 配置请求 xhr.responseType = "json" // 1.传递参数方式一: get -> query // xhr.open("get", "http://123.207.32.32:1888/02_param/get?name=why&age=18&address=广州市") // 2.传递参数方式二: post -> urlencoded // xhr.open("post", "http://123.207.32.32:1888/02_param/posturl") // // 发送请求(请求体body) // xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") // xhr.send("name=why&age=18&address=广州市") // 3.传递参数方式三: post -> formdata // xhr.open("post", "http://123.207.32.32:1888/02_param/postform") // // formElement对象转成FormData对象 // const formData = new FormData(formEl) // xhr.send(formData) // 4.传递参数方式四: post -> json xhr.open("post", "http://123.207.32.32:1888/02_param/postjson") xhr.setRequestHeader("Content-type", "application/json") xhr.send(JSON.stringify({name: "why", age: 18, height: 1.88})) }
XHR-Ajax网络请求封装
1
// 练习hyajax -> axios function hyajax({ url, method = "get", data = {}, headers = {}, // token success, failure } = {}) { // 1.创建对象 const xhr = new XMLHttpRequest() // 2.监听数据 xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { success && success(xhr.response) } else { failure && failure({ status: xhr.status, message: xhr.statusText }) } } // 3.设置类型 xhr.responseType = "json" // 4.open方法 if (method.toUpperCase() === "GET") { const queryStrings = [] for (const key in data) { queryStrings.push(`${key}=${data[key]}`) } url = url + "?" + queryStrings.join("&") xhr.open(method, url) xhr.send() } else { xhr.open(method, url) xhr.setRequestHeader("Content-type", "application/json") xhr.send(JSON.stringify(data)) } return xhr } // 调用者 hyajax({ url: "http://123.207.32.32:1888/02_param/get", method: "GET", data: { name: "why", age: 18 }, success: function(res) { console.log("res:", res) }, failure: function(err) { // alert(err.message) } }) // hyajax({ // url: "http://123.207.32.32:1888/02_param/postjson", // method: "post", // data: { // name: "jsondata", // age: 22 // }, // success: function(res) { // console.log("res:", res) // }, // failure: function(err) { // // alert(err.message) // } // })
XHR-Ajax网络请求工具
hyajax_promise.js
// 练习hyajax -> axios function hyajax({ url, method = "get", data = {}, timeout = 10000, headers = {}, // token } = {}) { // 1.创建对象 const xhr = new XMLHttpRequest() // 2.创建Promise const promise = new Promise((resolve, reject) => { // 2.监听数据 xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { resolve(xhr.response) } else { reject({ status: xhr.status, message: xhr.statusText }) } } // 3.设置类型 xhr.responseType = "json" xhr.timeout = timeout // 4.open方法 if (method.toUpperCase() === "GET") { const queryStrings = [] for (const key in data) { queryStrings.push(`${key}=${data[key]}`) } url = url + "?" + queryStrings.join("&") xhr.open(method, url) xhr.send() } else { xhr.open(method, url) xhr.setRequestHeader("Content-type", "application/json") xhr.send(JSON.stringify(data)) } }) promise.xhr = xhr return promise }
hyajax.js
// 练习hyajax -> axios function hyajax({ url, method = "get", data = {}, timeout = 10000, headers = {}, // token success, failure } = {}) { // 1.创建对象 const xhr = new XMLHttpRequest() // 2.监听数据 xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { success && success(xhr.response) } else { failure && failure({ status: xhr.status, message: xhr.statusText }) } } // 3.设置类型 xhr.responseType = "json" xhr.timeout = timeout // 4.open方法 if (method.toUpperCase() === "GET") { const queryStrings = [] for (const key in data) { queryStrings.push(`${key}=${data[key]}`) } url = url + "?" + queryStrings.join("&") xhr.open(method, url) xhr.send() } else { xhr.open(method, url) xhr.setRequestHeader("Content-type", "application/json") xhr.send(JSON.stringify(data)) } return xhr }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- <script src="./utils/hyajax.js"></script> --> <script src="./utils/hyajax_promise.js"></script> <script> const promise = hyajax({ url: "http://123.207.32.32:1888/02_param/get", data: { username: "coderwhy", password: "123456" } }) promise.then(res => { console.log("res:", res) }).catch(err => { console.log("err:", err) }) </script> </body> </html>
XHR-超时时间-取消请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button>取消请求</button> <script> const xhr = new XMLHttpRequest() xhr.onload = function() { console.log(xhr.response) } xhr.onabort = function() { console.log("请求被取消掉了") } xhr.responseType = "json" // 1.超市时间的设置 xhr.ontimeout = function() { console.log("请求过期: timeout") } // timeout: 浏览器达到过期时间还没有获取到对应的结果时, 取消本次请求 // xhr.timeout = 3000 xhr.open("get", "http://123.207.32.32:1888/01_basic/timeout") xhr.send() // 2.手动取消结果 const cancelBtn = document.querySelector("button") cancelBtn.onclick = function() { xhr.abort() } </script> </body> </html>
Fetch-Fetch函数基本使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 1.fetch发送get请求 // 1.1.未优化的代码 // fetch("http://123.207.32.32:8000/home/multidata").then(res => { // // 1.获取到response // const response = res // // 2.获取具体的结果 // response.json().then(res => { // console.log("res:", res) // }) // }).catch(err => { // console.log("err:", err) // }) // 1.2. 优化方式一: // fetch("http://123.207.32.32:8000/home/multidata").then(res => { // // 1.获取到response // const response = res // // 2.获取具体的结果 // return response.json() // }).then(res => { // console.log("res:", res) // }).catch(err => { // console.log("err:", err) // }) // 1.3. 优化方式二: // async function getData() { // const response = await fetch("http://123.207.32.32:8000/home/multidata") // const res = await response.json() // console.log("res:", res) // } // getData() // 2.post请求并且有参数 async function getData() { // const response = await fetch("http://123.207.32.32:1888/02_param/postjson", { // method: "post", // // headers: { // // "Content-type": "application/json" // // }, // body: JSON.stringify({ // name: "why", // age: 18 // }) // }) const formData = new FormData() formData.append("name", "why") formData.append("age", 18) const response = await fetch("http://123.207.32.32:1888/02_param/postform", { method: "post", body: formData }) // 获取response状态 console.log(response.ok, response.status, response.statusText) const res = await response.json() console.log("res:", res) } getData() </script> </body> </html>
XHR-文件上传的接口演练
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input class="file" type="file"> <button class="upload">上传文件</button> <script> // xhr/fetch const uploadBtn = document.querySelector(".upload") uploadBtn.onclick = function() { // 1.创建对象 const xhr = new XMLHttpRequest() // 2.监听结果 xhr.onload = function() { console.log(xhr.response) } xhr.onprogress = function(event) { console.log(event) } xhr.responseType = "json" xhr.open("post", "http://123.207.32.32:1888/02_param/upload") // 表单 const fileEl = document.querySelector(".file") const file = fileEl.files[0] const formData = new FormData() formData.append("avatar", file) xhr.send(formData) } </script> </body> </html>
Fetch-文件上传的接口演练
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input class="file" type="file"> <button class="upload">上传文件</button> <script> // xhr/fetch const uploadBtn = document.querySelector(".upload") uploadBtn.onclick = async function() { // 表单 const fileEl = document.querySelector(".file") const file = fileEl.files[0] const formData = new FormData() formData.append("avatar", file) // 发送fetch请求 const response = await fetch("http://123.207.32.32:1888/02_param/upload", { method: "post", body: formData }) const res = await response.json() console.log("res:", res) } </script> </body> </html>