Ajax运行原理
Ajax相当于浏览器发送请求与接受响应的代理人,以实现不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验
实现步骤
- 创建Ajax对象
new XMLHttpRequest()
- 告诉Ajax请求地址以及请求方式
open
- 发送请求
send
方法 - 获取服务器端给予客户端的响应数据 onload 获取响应数据
responseText
查看答案
1 2 3 4 5 6 7 8 9 10
| var xhr = new XMLHttpRequest()
xhr.open('get', 'http://localhost:3000/first')
xhr.send()
xhr.onload = function(){ console.log(xhr.responseText); }
|
响应的数据格式
- json对象作为响应数据的格式,请求返回的数据为json字符串
- 将json字符串转化为json对象
查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var xhr = new XMLHttpRequest()
xhr.open('get', 'http://localhost:3000/responseData')
xhr.send()
xhr.onload = function(){
let respnseText = JSON.parse(xhr.responseText) console.log(respnseText); console.log(typeof respnseText);
let str = `<h2>${respnseText.name}</h2>` document.body.innerHTML = str }
|
请求参数传递
- get请求
xx.open('get',url)
查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| let username =document.querySelector('#username') let email =document.querySelector('#email') let submit =document.querySelector('#submit')
submit.onclick = function(){ let emaildata = email.value let usernamedata = username.value let str = `username=${usernamedata}&email=${emaildata}` console.log(str); let xhr = new XMLHttpRequest() xhr.open('get',`http://localhost:3000/get?${str}`) xhr.send() xhr.onload = function(){ console.log(xhr.responseText); } }
|
- get请求只能的请求头类型只能是
application/x-www-form-urlencoded
,并且在解析请求地址时通过 body-parser中的urlencoded()方法进行解析,get请求不能提交对象数据格式的
post请求方式
- 请求的方式为json时,如果要得到请求的json内容 需要使用 body-parser中的bodyPaser.json()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var xhr = new XMLHttpRequest()
xhr.open('post', 'http://localhost:3000/json') xhr.setRequestHeader('Content-Type','application/json');
xhr.send(JSON.stringify({name:'list',age:50}))
xhr.onload = function(){ console.log(xhr.responseText); }
|
ajax状态码
- 获取服务器端的响应
- 0 请求未初始化
- 1 请求以及简历,但是还没有发送
- 2 请求已经发送
- 3 表示请求正在处理中,部分代码可以使用
- 4 响应已经完成
- xhr.readyState 获取Ajax状态码 onreadystatechange事件
- onload比以上事件的请求方式更为效率
ajax错误处理
- xhr.status获取http状态码 400
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var btn = document.getElementById('btn') btn.onclick=()=>{ var xhr = new XMLHttpRequest() xhr.open('get','http://localhost:3000/error') xhr.send(); xhr.onload=()=>{ console.log(xhr.status); if(xhr.status === 400){ alert(xhr.responseText) } } }
|
- 404错误状态码 输入错误的情况较多 ,检测请求地址是否有误
- 500错误代码时服务器端错误
- 断网时无法触发onload事件,可以执行onerror()事件
注意
ajax状态码表示的是服务器的请求过程的状态,http状态码表示的是请求的结果
低版本的缓存问题
- 在请求地址上加一个参数,并且保证每次请求参数的值不同即可
同步异步
- 封装一个简单的异步函数
get
- get请求需要拼接到请求地址的后方,post请求放在send的方法中
查看答案
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
| function ajax (params){ let xhr = new XMLHttpRequest(); let options = '' params.data.forEach((v,i)=>{ params += v + '=' + params.data[i] + '&' }) params.substr(0,params.length-1) xhr.open( params.type,params.url ) xhr.send() xhr.onload = ()=>{ params.success(xhr.responseText) } } ajax({ type:'get', url:'http://localhost:3000/first1', data:{ name:'zs', age:20 } success:(data)=>{ console.log('这里是success函数'+data); } })
|
- 封装get请求和post请求参数的时候
查看答案
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| function ajax(params) { let xhr = new XMLHttpRequest(); let options = '' for (let attr in params.data) { options += attr + '=' + params.data[attr] + '&' } options = options.substr(0, options.length - 1) if (params.type === 'get') { params.url = params.url + '?' + options } xhr.open(params.type, params.url) if (params.type == 'post') { let contentType = params.header['Content-Type'] xhr.setRequestHeader('Content-Type', contentType) if (contentType === 'application/json') { xhr.send(JSON.stringify(params.data)) } else { xhr.send(options) } } else { xhr.send() } xhr.onload = () => { if (xhr.status == 200) { let responseHeader = xhr.getResponseHeader('Content-Type') let resText = xhr.responseText if (responseHeader.includes('application/json')) { resText = JSON.parse(resText) } params.success(resText, xhr) } else { params.error(resText, xhr) } } } ajax({ type: 'get', url: 'http://localhost:3000/responseData', data: { name: 'sz', age: 20 }, header: { 'Content-Type': 'application/json' }, success: (data,xhr) => { console.log('这里是success函数'); console.log(data); console.log(xhr); }, error: (data) => { console.log('这里是error函数' + data); } })
|
- 获取请求中的数据
getResponseHeader()
方法 在页面加载完成后调用onload
事件中 如果获取到的请求类型为application/json
类型,将json字符串以json对象的方式输出,使用方法JSON.parse()
Object.assign()
如果目标对象和源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性。如果该函数只有一个参数,当参数为对象时,直接返回该对象;当参数不是对象时,会先将参数转为对象然后返回。并且该方法是浅拷贝
查看答案
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| function ajax(params) { let defaults = { type: 'get', url: '', data: {}, header: { 'Content-Type': 'application/x-www-form-urlencoded' }, success: (data) => {
}, error: (data) => {
} } Object.assign(defaults,params) let xhr = new XMLHttpRequest(); let options = '' for (let attr in params.data) { options += attr + '=' + defaults.data[attr] + '&' } options = options.substr(0, defaults.length - 1) if (defaults.type === 'get') { defaults.url = defaults.url + '?' + options } xhr.open(defaults.type, defaults.url) if (defaults.type == 'post') { let contentType = defaults.header['Content-Type'] xhr.setRequestHeader('Content-Type', contentType) if (contentType === 'application/json') { xhr.send(JSON.stringify(defaults.data)) } else { xhr.send(options) } } else { xhr.send() } xhr.onload = () => { if (xhr.status == 200) { let responseHeader = xhr.getResponseHeader('Content-Type') let resText = xhr.responseText if (responseHeader.includes('application/json')) { resText = JSON.parse(resText) } defaults.success(resText, xhr) } else { defaults.error(resText, xhr) } } } ajax({ url: 'http://localhost:3000/responseData', data: { name: 'sz', age: 20 }, success: (data, xhr) => { console.log('这里是success函数'); console.log(data); console.log(xhr); } })
|
模板引擎
- 使用模板引擎
art-template
在客户端的使用步骤
查看答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!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>模板引擎</title> <script src="/js/art-template.js"></script> </head> <body> <div class="container"></div> <script type="text/html" id="idt"> <h1>{{username}} {{age}}</h1> </script> <script type="text/javascript"> let html = template('idt',{username:'zs',age:20}) document.querySelector('.container').innerHTML = html </script> </body> </html>
|
验证邮箱
查看答案
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| <!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>验证邮箱地址</title> <script src="/js/ajax.js"></script> </head>
<body> <style> body { background: -webkit-linear-gradient(left, rgb(216, 236, 235), rgb(241, 229, 241)); }
.box { margin: 200px auto; display: flex; justify-content: center; align-items: center; flex-direction: column; }
.email_login { border-radius: 10px; width: 400px; height: 30px; padding: 10px; }
.email_login:hover { outline-color: bisque; border: none; }
.message { background: rgb(221, 208, 208); }
.success { background-color: rgb(82, 82, 173); }
.error { background-color: rgb(226, 106, 106); } </style> <div class="box"> <input type="email" class="email_login" value="" placeholder="请在此输入您要初测的邮箱账号!!"> <p class="message"></p> </div> <script type="text/javascript"> let email = document.querySelector('.email_login') let message = document.querySelector('p') email.onblur = function () { let email_value = this.value let reg = /^[a-zA-Z0-9_-][email protected][a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/ if (!reg.test(email_value)) { message.innerHTML = '输入的邮箱规则格式有误,请重新输入!!!' message.className = 'message' return; } ajax({ type: 'post', url: "http://localhost:3000/emailbox", data: { email: email_value }, success: function (response) { if (response.message.includes('恭喜')) { message.innerHTML = response.message message.className = 'success' } else { message.innerHTML = response.message message.className = 'error' } }, error: (res) => { message.innerHTML = res.message message.className = 'error' } }); }
</script> </body> </html>
|
请求路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| app.get('/emailbox',(req,res)=>{ if(req.query.email == '[email protected]'){ res.send({message:'您好邮箱已注册,请您重新输入!!'}) }else{ res.send({message:'恭喜您注册的邮箱可用!!!!'}) } }) app.post('/emailbox',(req,res)=>{ if(req.body.email == '[email protected]'){ res.send({message:'您好邮箱已注册,请您重新输入!!'}) }else{ res.send({message:'恭喜您注册的邮箱可用!!!!'}) } })
|
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 43 44 45 46 47 48 49 50
| function ajax(params) { let defaults = { type: 'get', url: '', data: {}, header: { 'Content-Type': 'application/json' }, success: (data) => {}, error: (data) => {} } Object.assign(defaults,params) let xhr = new XMLHttpRequest(); let options = '' for (let attr in params.data) { options += attr + '=' + defaults.data[attr] + '&' } options = options.substr(0, defaults.length - 1) if (defaults.type === 'get') { defaults.url = defaults.url + '?' + options } xhr.open(defaults.type, defaults.url) if (defaults.type == 'post') { let contentType = defaults.header['Content-Type'] xhr.setRequestHeader('Content-Type', contentType) if (contentType === 'application/json') { xhr.send(JSON.stringify(defaults.data)) } else { xhr.send(options) } } else { xhr.send() } xhr.onload = () => { if (xhr.status == 200) { let responseHeader = xhr.getResponseHeader('Content-Type') let resText = xhr.responseText if (responseHeader.includes('application/json')) { resText = JSON.parse(resText) } defaults.success(resText, xhr) } else { defaults.error(resText, xhr) } } }
|
搜索框内容自动提示
- 使用定时器的操作,延时对请求接口发送ajax请求,在每次请求之前将之前的定时器清除
- 设置防抖操作,对用户输入的值进行判断如果用户没有在手术框中输入内容,将提示信息 使用trim()函数,将文本框中的空格清除 阻止程序向下执行
return
三级联动(省市区)
- 接口地址:接口地址
- JSON.stringify() 方法可以将对象的数据存储在本地的内存中
查看答案
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| <!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>三级联动 省市区</title> <script src="js/ajax.js"></script> <script src="js/art-template.js"></script> </head> <style> body { background-color: #ccc; }
.box { margin: 100px auto; width: 500px; height: 300px; display: flex; justify-content: center; align-items: center; } </style>
<body> <div class="box"> <div class="form_group"> <select name="" id="province"> </select> </div> <div class="form_group"> <select name="" id="city"> <option value="">请选择城市</option> </select> </div> <div class="form_group"> <select name="" id="area"> <option value="">请选择县城</option> </select> </div> </div> </body> <script type="text/html" id="provinceTpl"> <option value="">请选择省份</option> {{each provices_list}} <option value="{{$value.pindex}}">{{$value.provices_list}}</option> {{/each}} </script> <script type="text/html" id="cityTpl"> <option value="">请选择城市</option> {{each city_lists}} <option value="">{{$value.citysName}}</option> {{/each}} </script> <script> let All_lists = [] function getaddressData() { ajax({ type: "get", url: "https://cloud.mr90.top/hexo/4/province1.json", success: function (response) { console.log(response); All_lists = response.provinces localStorage.setItem('address_data', JSON.stringify(response.provinces)) } }); } let province = document.querySelector('#province') let city = document.querySelector('#city') let addressData = localStorage.getItem('address_data') if (!addressData) { this.getaddressData() } else { All_lists = JSON.parse(addressData) let provices_list = All_lists.map((v,i) => { let arr = {provices_list:v.provinceName,pindex:i} return arr }) let html = template('provinceTpl',{provices_list}) province.innerHTML = html } province.onchange = function(e){ let id = this.value let city_lists = JSON.parse(addressData)[Number(id)].citys let html1 = template('cityTpl',{city_lists}) city.innerHTML = html1 } </script>
</html>
|
- 模拟HTML表单
- 异步上传二进制文件
- 本身是一个构造函数
- 使用formidable模块来解析FormData对象
- formData.get(‘属性名’),formData.set(‘属性名’,’属性值’),formData.delete(‘key’),formData.append(‘key’,’value’)
- 默认接收最后一个实例方法
- set方法和append方法的区别:在属性名已经存在的情况下,set会覆盖原来的键名的值,append会保留两个值
查看答案
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
| <!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>FormData对象</title> </head> <body> <form id="form"> <input type="text" name="username" id="" /> <input type="password" name="password" id="" /> <input type="button" id="btn" value="提交"/> </form> <script type="text/javascript"> var btn = document.querySelector('#btn') var form = document.querySelector('#form') btn.onclick = function(){ let formData = new FormData(form) let xhr = new XMLHttpRequest() xhr.open('post','http://localhost:3000/formData') xhr.send(formData) xhr.onload = function(){ if(xhr.status==200){ console.log(xhr.responseText); } } } </script> </body> </html>
|
配置路由
1 2 3 4 5 6 7
| app.post('/formData',(req,res)=>{ const form = new formidable.IncomingForm(); form.parse(req,(err,fields,files)=>{ res.send(fields) }) })
|
- get请求方式不能用于文件的上传
查看答案
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
| <!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>FormData二进制文件的上传</title> </head>
<body> <input type="file" name="" id="file" /> <script type="text/javascript"> let file = document.querySelector('#file') file.onchange = function(){ let formData = new FormData() formData.append('attrName',this.files[0]) var xhr = new XMLHttpRequest() xhr.open('post','http://localhost:3000/up_file') xhr.send(formData) xhr.onload = function(){ if(xhr.status==200){ console.log(xhr.responseText); } } } </script> </body>
</html>
|
上传进度条
- 使用上传事件中的
onprogress
事件
查看答案
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 43 44 45 46 47 48 49 50 51 52
| <!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>上传进度条</title> </head> <style> .progress_warp{ width: 800px; height: 40px; background-color: #ccc; border-radius: 5px; } .progress_event{ border-radius: 5px; width: 0; height: 100%; color: #fff; background-color: rgb(53, 27, 68); } </style> <body> <input type="file" name="" id="file" /> <div class="progress_warp"> <div class="progress_event" style="width: 0%;" id="bar"></div> </div> <script type="text/javascript"> let file = document.querySelector('#file') let bar = document.querySelector('#bar') file.onchange = function(){ let formData = new FormData() formData.append('attrName',this.files[0]) var xhr = new XMLHttpRequest() xhr.open('post','http://localhost:3000/up_file') xhr.upload.onprogress = function(e){ let bar_data = (e.loaded / e.total).toFixed(2) * 100 + '%' bar.style.width = bar_data bar.innerHTML = bar_data } xhr.send(formData) xhr.onload = function(){ if(xhr.status==200){ console.log(xhr.responseText); } } } </script> </body> </html>
|
图片加载预览
查看答案
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| <!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>上传进度条</title> </head> <style> .progress_warp{ width: 800px; height: 40px; background-color: #ccc; border-radius: 5px; } .box_img{ padding: 20px; } .box_img img{ width: 100px; border-radius: 10px; } .progress_event{ border-radius: 5px; width: 0; display: flex; justify-content: center; align-items: center; font-size: 20px; font-weight: 550; margin: 10px 0; height: 100%; color: #fff; background-color: rgb(53, 27, 68); } </style> <body> <input type="file" name="" id="file" /> <div class="box_img"> </div> <div class="progress_warp"> <div class="progress_event" style="width: 0%;" id="bar"></div> </div> <script type="text/javascript"> let file = document.querySelector('#file') let bar = document.querySelector('#bar') let box_img = document.querySelector('.box_img') file.onchange = function(){ let formData = new FormData() formData.append('attrName',this.files[0]) var xhr = new XMLHttpRequest() xhr.open('post','http://localhost:3000/up_file') xhr.upload.onprogress = function(e){ let bar_data = (e.loaded / e.total).toFixed(2) * 100 + '%' bar.style.width = bar_data bar.innerHTML = bar_data } xhr.send(formData) xhr.onload = function(){ if(xhr.status==200){ let img = document.createElement('img') img.src= '/uploads' + JSON.parse(xhr.responseText).path img.onload = function (){ box_img.appendChild(img) } } } } </script> </body> </html>
|
ajax问题
- ajax不能向非同源服务器端发送请求
- 使用jsonp解决同源限制问题
- 将不同源的服务器请求地址写在script标签的src属性中
- 服务端响应数据必须是以一个函数的调用
- 在客户端全局作用域下定义函数fn(在script标签的上面)
- 在函数内部对服务器端返回的数据进处理
post请求格式
- 必须有请求头:content-type:application/x-www-form-unlencoded
查看解析
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
| <!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>post请求的两种方式</title> </head>
<body>
<script type="text/javascript"> let xhr = new XMLHttpRequest() xhr.open('post', 'http://localhost:3000/post') xhr.setRequestHeader('Content-Type', 'application/json') params = { name: 'zs', age: 2 } xhr.send(JSON.stringify(params)) xhr.onload = function () { console.log(xhr.responseText); } </script> </body> </html>
|
jsonp请求封装
查看客户端
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 43 44 45 46 47 48 49 50
| <!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>jsonp的调用</title> </head>
<body> <button id="btn1">jsonP提交</button> <button id="btn2">jsonP提交</button> <script> let btn1 = document.getElementById('btn1') let btn2 = document.getElementById('btn2') btn2.onclick = function () { jsonP({ url: 'http://localhost:3000/better', data:{ name:'zs', age:23 }, success: (e) => { console.log(e) console.log(123) } }) } function jsonP(e) { var script = document.createElement('script') params = '' for(let arr in e.data){ params+=`&${arr}=${e.data[arr]}` } fName = 'myjson' + Math.random().toString().replace('.', '') window[fName] = e.success script.src = e.url + `?callback=${fName+params}` document.body.appendChild(script) script.onload = function () { document.body.removeChild(script) } } </script> </body> </html>
|
查看服务器
}
1 2 3 4 5 6
| app.get('/better',(req,res)=>{ res.jsonp({name:'zs',age:98}) })
|
腾讯天气API
查看解析
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| <!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"> <script src="https://cdn.jsdelivr.net/gh/Rr210/[email protected]/js/jquery-3.5.1.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Rr210/[email protected]/frame/bootstrap/3/css/bootstrap.min.css"> <script src="https://cdn.jsdelivr.net/gh/Rr210/[email protected]/frame/bootstrap/3/js/bootstrap.min.js"></script> <script src="/js/art-template.js"></script> <title>Document</title> </head> <style> .ta{ margin: 100px; } th{ text-align: center; } </style> <body> <div class="ta table-responsive"> <table class="table table-striped table-bordered table-hover text-center"> <thead> <tr> <th>degree</th> <th>update_time</th> <th>weather</th> <th>weather_code</th> <th>weather_short</th> <th>wind_direction</th> <th>wind_power</th> </tr> </thead> <tbody id='html'></tbody> </table> </div> <script src="/js/jsonp.js"></script> <script type="text/html" id="tpl"> {{each info}} <tr> <td>{{$value.degree + '°'}}</td> <td class="">{{dateFormat($value.update_time)}}</td> <td>{{$value.weather}}</td> <td>{{$value.weather_code}}</td> <td>{{$value.weather_short}}</td> <td>{{$value.wind_direction}}</td> <td>{{$value.wind_power+'级'}}</td> </tr> {{/each}} </script> <script> let datas = document.getElementById('html') function dateFormat(dates){ let year = dates.substr(0,4) let mounth = dates.substr(4,2) let day = dates.substr(6,2) let hour = dates.substr(8,2) let min = dates.substr(10,2) return `${year}-${mounth}-${day} ${hour}:${min}` } template.defaults.imports.dateFormat = dateFormat jsonP({ url: 'https://wis.qq.com/weather/common', data: { source: 'pc', weather_type: 'forecast_1h|forecast_24h', province: '山西省', city: '晋中市' }, success: (e) => { let html = template('tpl', { info: e.data.forecast_1h }) datas.innerHTML = html } }) </script> </body>
</html>
|
cors 跨域资源共享
- 使用express方法 设置请求的报文
- 使用express模块中的中间件拦截请求 app.use
- 设置服务器的响应报文
res.header('Access-Control-Allow-Origin','*')
- 设置请求方法
res.header('Access-Control-Allow-Method':'get,post')
- 注意在使用中间件拦截时 一定要注意放行,否则无法执行后面的内容
next()
查看解析
}
1 2 3 4 5
| app.use((req,res,next)=>{ res.header('Access-Control-Allow-Origin','*') res.header('Access-Control-Allow-Methods','get,post') next() })
|
cookie复习
withCredentials
:指定在涉及到跨域请求时,是否携带cookie信息,默认值为falseAccess-Control-Allow-Credentials
:true 允许客户端发送请求时携带cookie
查看解析
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 43 44
| <!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>设置cook信息</title> </head>
<body> <form id="loginForm"> <input type="text" placeholder="用户名" name="username" /> <input type="password" placeholder="密码" name="pwd" /> </form> <button id="logined">登录</button> <button id="checklogin">检测登录</button> <script> let loginform = document.getElementById('loginForm') let logined = document.getElementById('logined') let checklogin = document.getElementById('checklogin') logined.onclick = function () { let formData = new FormData(loginform) let xhr = new XMLHttpRequest() xhr.open('post', 'http://localhost:3000/logins') xhr.withCredentials = true xhr.send(formData) xhr.onload = function () { console.log(xhr.responseText); } } checklogin.onclick = function(){ let xhr = new XMLHttpRequest() xhr.open('get', 'http://localhost:3000/checklogin') xhr.send() xhr.onload = function () { console.log(xhr.responseText); } } </script> </body> </html>
|
查看解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| app.post('/logins', (req, res) => { const form = new formidable.IncomingForm(); form.parse(req, (err, fields, files) => { console.log(fields); if (fields.username == '123' && fields.pwd == '123') { req.session.isLogin = true res.send({ message: '登录成功', code: 1 }) } else { res.send({ message: '登录失败', code: -1 }) } }) }) app.get('/checklogin', (req, res) => { if (req.session.isLogin) { res.send({ message: '当前已登录' }) }else{ res.send({message:'当前未登录'}) } })
|
jquery中的$.ajax()
- 请求参数时,默认为application/x-www-form-encoded
- 如果使用json对象,需要将json对象转换成json字符串,并且将类型设置为application/json
beforeSend
表示在发送ajax请求前执行的 可在其中测试传递的参数,不满足条件可以使用return false
seralize方法
- 将表单中的数据自动拼接成字符串类型,如:
name=zs&age=12
- 使用
sealizeArray()
方法将用户输入的内容转换成数组形式 - 封装一个函数使数组形式转换为json对象
查看解析
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
| <!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>使用jquery中的serialize方法</title> </head>
<body> <form id="form"> <input type="text" name="username" placeholder="用户名" /> <input type="password" name="pwd" placeholder="用户名" /> <input type="submit" value="提交" /> </form> <script src="https://cdn.jsdelivr.net/gh/Rr210/[email protected]/js/jquery-3.5.1.min.js"></script> <script> $('#form').on('submit', function () { serializeObject($(this)) return false }) function serializeObject(obj) { let result = {} let params = obj.serializeArray() $.each(params,(index,item)=>{ result[item.name] = item.value }) console.log(result); return result } </script> </body>
</html>
|
$.ajax() 发送jsonp请求
dataType:'jsonp'
jsonCallback:'fnName'
指定函数名称jsonp:'cb'
修改callback名称
查看解析
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
| <!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>使用jquery中的jsonp方法</title> <script src="https://cdn.jsdelivr.net/gh/Rr210/[email protected]/js/jquery-3.5.1.min.js"></script> </head> <body> <button id="btn"> 发送请求 </button> <script> $('#btn').on('click',function(){ $.ajax({ url:"/jsonp", type:'get', dataType:'jsonp', success:(res)=>{ console.log(res); } }) }) </script> </body> </html>
|
todoList 案例
- GitHub地址:【github】
- 使用技术
node.js+express+mongoose
ajax请求
- ajaxStart方法为当页面中有ajax请求时触发
- ajaxComplete 方法为当页面中ajax请求完成时触发
RESful风格
- 规范API设计
get/put/delete/
req.params
获取get请求参数 地址为:user/:id
XML是可扩展标记语言
- 作用是传输和存储数据
- XML DOM 即XML文档对象模型
查看解析
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
| <!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>XML的获取</title> </head> <body> <button id="btn">发送请求</button> <div class="container"></div> <script type="text/javascript"> let btn = document.getElementById('btn') let container = document.getElementsByClassName('container') btn.onclick = function(){ let xhr = new XMLHttpRequest() xhr.open('get','https://u.mr90.top/other/atom.xml') xhr.send() xhr.onload = function(){ let xmlDocument = xhr.responseXML let title = xmlDocument.querySelectorAll('entry title') let arr = [...title] let title_all = arr.map(v=>v.innerHTML) let html = template('tit',{title_all}) container.innerHTML = html } } </script> </body> </html>
|
数组转换
- 使用
Array.prototype.slice.call(nodes,0)
nodes为伪数组 - 使用es6中的方法
[...arr]
或者使用Array.from(obj)
的方法进行转换