表单请求
也就是form表单
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <form action="xxx" method="get"> <label>用户名<input type="text" name="username" placeholder="请输入用户名"/></label><br/> <label>密码<input type="password" name="password"/></label><br/> 性别 <label><input type="radio" name="sex" value="man"/>男</label> <label><input type="radio" name="sex" value="women"/>女</label><br/> 爱好 <label><input type="checkbox" name="zzzz" value="chang" checked="checked" id="ddd"/>唱</label> <label><input type="checkbox" name="zzzz" value="tiao"/>跳</label> <label><input type="checkbox" name="zzzz" value="rap"/>rap</label> <label><input type="checkbox" name="zzzz" value="lanqiu"/>篮球</label><br/> <input type="button" value="普通按钮"/><input type="submit" value="注册"/><br/> <input type="hidden" name="hd" value="jack"/><br/> </form>
|
ajax请求
ajax可以在不刷新网页的情况下,向服务器发送异步HTTP请求
xhr就是ajax的一种实现,ajax是代表的是一种开发模式,而不是具体的 API,它的核心目标是:使用 JavaScript 进行异步数据请求,从而提升网页的交互体验,ajax请求受同源策略限制
原生ajax发送GET请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| let xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.open("GET", "http://localhost:8080/register?username=1&password=2&time=" + new Date().getTime());
xmlHttpRequest.send(); xmlHttpRequest.onreadystatechange = function () { if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) { console.log(xmlHttpRequest.response); console.log(xmlHttpRequest.responseText); console.log(xmlHttpRequest.getAllResponseHeaders()); console.log(xmlHttpRequest.getResponseHeader('content-type')); } }
|
原生ajax发送POST请求
1 2 3 4 5 6 7 8 9 10 11 12 13
| let xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.open("POST", "http://localhost:8080/register?time=" + new Date().getTime()); xmlHttpRequest.setRequestHeader('name', 'ja'); xmlHttpRequest.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); xmlHttpRequest.send('username=1&password=2'); xmlHttpRequest.onreadystatechange = function () { if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) { console.log(xmlHttpRequest.response); console.log(xmlHttpRequest.responseText); console.log(xmlHttpRequest.getAllResponseHeaders()); console.log(xmlHttpRequest.getResponseHeader('content-type')); } }
|
jquery中的ajax
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| $.get('http://localhost:8080/register?time=' + new Date().getTime(), "username=jack", function (data) { console.log(data); }); $.get('http://localhost:8080/register?time=' + new Date().getTime(), {username: 'jack', age: 34}, function (data) { console.log(data); });
$.post('http://localhost:8080/register?time=' + new Date().getTime(), "username=jack", function (data) { console.log(data); }); $.post('http://localhost:8080/register?time=' + new Date().getTime(), {username: 'jack', age: 34}, function (data) { console.log(data); });
$.ajax({ method: 'POST', url: 'http://localhost:8080/register?time=' + new Date().getTime(), data: {username: 'jack', age: 34}, success: function (data) { console.log(data); }, headers: { name: 'jack' } });
$.ajax({ method: 'POST', url: 'http://localhost:8080/register?time=' + new Date().getTime(), data: "username=jack", headers: { name: 'jack' } }).done(function (data) { console.log(data); });
|
fech发送ajax请求
fech里的.then
方法返回的也是Promise
类型
1 2 3 4 5 6 7 8 9 10 11 12
| fetch('http://localhost:8080/register?time=' + new Date().getTime(), { method: 'POST', headers: { name: 'xiaojianbang' }, body: 'username=xiaojianbang&password=a12345678' } ).then(function (response) { return response.text(); }).then(function (data){ console.log(data); });
|
axios发送ajax请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| axios.get('http://localhost:8080/register?time=' + new Date().getTime(), { params: { username: 'xiaojianbang', password: 'a12345678' }, headers: { name: 'xiaojianbang' } }).then(function (response) { console.log(response.data); });
axios.post('http://localhost:8080/register?time=' + new Date().getTime(), { username: 'xiaojianbang', password: 'a12345678' }, { params: { getparam: 'xxxx' }, headers: { name: 'xiaojianbang' } }).then(function (response) { console.log(response.data); });
axios({ method: 'POST', url: 'http://localhost:8080/register?getparam=xxx', params: { timestamp: new Date().getTime() }, data: { username: 'xiaojianbang', password: 'a12345678' }, headers: { name: 'xiaojianbang' } }).then(function (response) { console.log(response.data); });
|
jsonp跨域请求
通过script
标签直接发起请求,请求成功之后新创建标签,把获取到的数据插入到新建的script
标签里,jsonp请求可以跨域
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script> function xiaojianbang(data) { data = "前端再加工一下:" + data; console.log("myCallback", data); } let scriptElement = document.createElement('script'); scriptElement.src = "http://localhost:8080/register?username=jack&password=a12345678&callback=xiaojianbang" ; document.body.appendChild(scriptElement);
$.getJSON('http://localhost:8080/register?username=xiaojianbang&password=a12345678&callback=?', function(retval){ console.log(retval); }); </script>
|
jsonp回调函数
JSONP之所以能够跨域请求并执行回调函数,关键在于 <script>
标签的特性以及浏览器对 JavaScript 代码的执行方式。
执行原理
首先前端发起 JSONP 请求
1
| <script src="https://example.com/api?callback=funcname"></script>
|
由于 <script>
标签的 src
属性可以加载任意域的 JavaScript 代码,因此不会受到浏览器的同源策略限制。
callback=funcname
作为查询参数,告知服务器返回的 JSON 数据应如何包装。
然后服务器响应,服务器收到请求后,通常会解析 callback
参数,并返回如下格式的数据,服务器动态生成一段 JavaScript 代码,调用 funcname
,并将数据作为参数传递。
1
| funcname({ "message": "Hello, JSONP!" });
|
然后浏览器解析并执行
1
| funcname({ "message": "Hello, JSONP!" });
|
由于 funcname
之前已经在前端定义,浏览器会调用它,并将服务器返回的数据作为参数传递。
demo
前端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>JSONP 示例</title> </head> <body> <script> function funcname(data) { console.log("收到的数据:", data); } </script> <script src="https://example.com/api?callback=funcname"></script> </body> </html>
|
服务器返回
1
| funcname({"message": "Hello, JSONP!"});
|
由于服务器返回的数据是被前端的script
标签中请求返回的,所以会被当成js代码执行
Promise
主要是解决连续异步请求,一个页面如果有很多异步请求,而且这些请求之间必须有顺序,比如先获取用户登录状态、再获取用户信息,这就会导致很多层嵌套
1 2 3 4 5 6 7 8 9
| setTimeout(() => { console.log("任务 1 完成"); setTimeout(() => { console.log("任务 2 完成"); setTimeout(() => { console.log("任务 3 完成"); }, 1000); }, 1000); }, 1000);
|
Promise的使用
1 2 3 4 5 6 7 8 9 10 11 12
| let promise = new Promise(function (resolve, reject) { ...; });
promise.then(function (data) { console.log('data', data); }, function (err) { console.log('err', err); });
|
对于逆向来说,不用知道各种promise的状态,只需要知道当new Promise
里面的方法被执行的时候,只能二选一执行下面的函数,至于走哪个,可以断点调试
同一个promise可以有多个then方法,而且then方法的第二个函数参数可以不传,当resolve方法被执行的时候,所有的then方法都会被执行
1 2 3 4 5 6 7 8 9 10 11 12
| let promise = new Promise(function (resolve, reject) { resolve('xiaojianbang'); }); promise.then(function (data) { console.log('then1:', data); }); promise.then(function (data) { console.log('then2:', data); }); promise.then(function (data) { console.log('then3:', data); });
|
Promise解决回调地狱
掌握几点,一是resolve
函数的参数,就是下面then
的第一个函数的参数,可以对数据进行处理,第二then
方法的返回值也是一个Promise
类型,所以可以.then
连续使用,简单理解就是按顺序往下依次异步请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| function httpRequest(method, url, data, resolve, reject) { let xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.open(method, url); xmlHttpRequest.setRequestHeader('name', 'xiaojianbang'); xmlHttpRequest.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); xmlHttpRequest.send(data); xmlHttpRequest.onreadystatechange = function () { if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) { resolve(xmlHttpRequest.responseText); } } }
new Promise(function (resolve, reject) { httpRequest("POST", "http://localhost:8080/register?time=" + new Date().getTime(), 'username=xiaojianbang&password=a12345678', resolve, reject); }).then(function (data) { console.log('注册返回的响应', data); return new Promise(function (resolve, reject){ httpRequest("POST", "http://localhost:8080/register?time=" + new Date().getTime(), 'username=xiaojianbang&password=a12345678', resolve, reject); }); }).then(function (data) { console.log('登录返回的响应', data); return new Promise(function (resolve, reject){ httpRequest("POST", "http://localhost:8080/register?time=" + new Date().getTime(), 'username=xiaojianbang&password=a12345678', resolve, reject); }); }).then(function (data) { console.log('获取到的用户信息', data); return new Promise(function (resolve, reject){ httpRequest("POST", "http://localhost:8080/register?time=" + new Date().getTime(), 'username=xiaojianbang&password=a12345678', resolve, reject); }); }).then(function (data) { console.log('订单获取结果', data); });
|