文章目录
来源博客:【Harryの心阁】
Ajax运行原理
Ajax相当于浏览器发送请求与接受响应的代理人,以实现不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验
实现步骤
- 创建Ajax对象
new XMLHttpRequest()
- 告诉Ajax请求地址以及请求方式
open
- 发送请求
send
方法 - 获取服务器端给予客户端的响应数据 onload 获取响应数据
responseText
// 1. 创建ajax对象
var xhr = new XMLHttpRequest()
// 2. 告诉ajax对象发送的位置,和方式,第一个参数是请求方式,第二个请求地址
xhr.open('get', 'http://localhost:3000/first')
// 3. 发送请求
xhr.send()
// 4. 获取响应数据
xhr.onload = function(){
console.log(xhr.responseText);
}
响应的数据格式
- json对象作为响应数据的格式,请求返回的数据为json字符串
- 将json字符串转化为json对象
// 1. 创建ajax对象
var xhr = new XMLHttpRequest()
// 2. 告诉ajax对象发送的位置,和方式,第一个参数是请求方式,第二个请求地址
xhr.open('get', 'http://localhost:3000/responseData')
// 3. 发送请求
xhr.send()
// 4. 获取响应数据,接受完请求后onload事件自动响应
xhr.onload = function(){
// 返回的是字符串类型
// console.log(xhr.responseText);
// 将json字符串转换为json对象
let respnseText = JSON.parse(xhr.responseText)
console.log(respnseText);
console.log(typeof respnseText);
// 将转换的json对象中的信息获取,并且将数据信息渲染到页面中
let str = `<h2>${respnseText.name}</h2>`
document.body.innerHTML = str
}
请求参数传递
- get请求
xx.open('get',url)
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}`
// 创建一个ajax对象
console.log(str);
let xhr = new XMLHttpRequest()
// 创建ajax对象的请求方式
xhr.open('get',`http://localhost:3000/get?${str}`)
xhr.send()
xhr.onload = function(){
console.log(xhr.responseText);
}
}
// res.send(req.query)
- get请求只能的请求头类型只能是
application/x-www-form-urlencoded
,并且在解析请求地址时通过 body-parser中的urlencoded()方法进行解析,get请求不能提交对象数据格式的
post请求方式
- 请求的方式为json时,如果要得到请求的json内容 需要使用 body-parser中的bodyPaser.json()方法
// 1. 创建ajax对象
var xhr = new XMLHttpRequest()
// 2. 告诉ajax对象发送的位置,和方式,第一个参数是请求方式,第二个请求地址
xhr.open('post', 'http://localhost:3000/json')
xhr.setRequestHeader('Content-Type','application/json');
// 3. 发送请求
xhr.send(JSON.stringify({name:'list',age:50}))
// 4. 获取响应数据,接受完请求后onload事件自动响应
xhr.onload = function(){
// 返回的是字符串类型
console.log(xhr.responseText);
// 将json字符串转换为json对象
}
ajax状态码
- 获取服务器端的响应
- 0 请求未初始化
- 1 请求以及简历,但是还没有发送
- 2 请求已经发送
- 3 表示请求正在处理中,部分代码可以使用
- 4 响应已经完成
- xhr.readyState 获取Ajax状态码 onreadystatechange事件
- onload比以上事件的请求方式更为效率
ajax错误处理
- xhr.status获取http状态码 400
var btn = document.getElementById('btn')
// 当用户点击后发送错误请求
btn.onclick=()=>{
var xhr = new XMLHttpRequest()
xhr.open('get','http://localhost:3000/error')
// 对请求的http的状态码进行判断
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的方法中
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请求参数的时候
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)
// console.log(options)
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 = () => {
// 对http的状态码进行判断如果状态码为200则调用success函数,如果失败则调用error函数
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'
// 'Content-Type':'application/x-www-form-urlencoded'
},
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()
如果目标对象和源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性。如果该函数只有一个参数,当参数为对象时,直接返回该对象;当参数不是对象时,会先将参数转为对象然后返回。并且该方法是浅拷贝
function ajax(params) {
// 给ajax设定一个默认值
let defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: (data) => {
},
error: (data) => {
}
}
// 使用Object.assign()方法 将之间的对象覆盖
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)
// console.log(options)
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 = () => {
// 对http的状态码进行判断如果状态码为200则调用success函数,如果失败则调用error函数
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
在客户端的使用步骤
<!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>
验证邮箱
<!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/template.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;
/* outline-color: aliceblue; */
}
.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 () {
// console.log(e);
// 获取用户输入的值,对用户输入的值判断
let email_value = this.value
// 正则判断输入的值
let reg = /^[a-zA-Z0-9_-]+@[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>
{% folding green, 请求路由 %}
app.get('/emailbox',(req,res)=>{
if(req.query.email == 'iui9@qq.com'){
res.send({message:'您好邮箱已注册,请您重新输入!!'})
}else{
res.send({message:'恭喜您注册的邮箱可用!!!!'})
}
})
app.post('/emailbox',(req,res)=>{
if(req.body.email == 'iui9@qq.com'){
res.send({message:'您好邮箱已注册,请您重新输入!!'})
}else{
res.send({message:'恭喜您注册的邮箱可用!!!!'})
}
})
{% folding green, ajax封装 %}
function ajax(params) {
// 给ajax设定一个默认值
let defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/json'
},
success: (data) => {},
error: (data) => {}
}
// 使用Object.assign()方法 将之间的对象覆盖
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)
// console.log(options)
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 = () => {
// 对http的状态码进行判断如果状态码为200则调用success函数,如果失败则调用error函数
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() 方法可以将对象的数据存储在本地的内存中
<!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">
<!-- <option value="">请选择省份</option> -->
</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://cdn.jsdelivr.net/gh/Rr210/image@master/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
})
// console.log(provices_list);
let html = template('provinceTpl',{provices_list})
province.innerHTML = html
}
// 给省份选择框添加一个改变事件监听 select的变化
province.onchange = function(e){
let id = this.value
let city_lists = JSON.parse(addressData)[Number(id)].citys
// console.log(city_lists);
let html1 = template('cityTpl',{city_lists})
city.innerHTML = html1
}
</script>
</html>
FormData对象的作用
- 模拟HTML表单
- 异步上传二进制文件
- 本身是一个构造函数
- 使用formidable模块来解析FormData对象
- formData.get(‘属性名’),formData.set(‘属性名’,‘属性值’),formData.delete(‘key’),formData.append(‘key’,‘value’)
- 默认接收最后一个实例方法
- set方法和append方法的区别:在属性名已经存在的情况下,set会覆盖原来的键名的值,append会保留两个值
<!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(){
// 将普通的html表单转换为表单对象
let formData = new FormData(form)
let xhr = new XMLHttpRequest()
xhr.open('post','http://localhost:3000/formData')
// 发送ajax请求
xhr.send(formData)
// 监听xhr对象下面的onload事件
xhr.onload = function(){
if(xhr.status==200){
console.log(xhr.responseText);
}
}
}
</script>
</body>
</html>
// 加入formidable模板
app.post('/formData',(req,res)=>{
const form = new formidable.IncomingForm();
form.parse(req,(err,fields,files)=>{
res.send(fields)
})
})
formData二进制上传
- get请求方式不能用于文件的上传
<!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
事件
<!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){
// console.log(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>
图片加载预览
<!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){
// console.log(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);
// 动态创建一个图片 将上传的文件的路径名称赋值给uploads
let img = document.createElement('img')
img.src= '/uploads' + JSON.parse(xhr.responseText).path
// 调用图片上传成功的事件onload
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
<!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>
<!-- 第一种使用url形式的请求方式 -->
<!-- <script type="text/javascript">
let xhr = new XMLHttpRequest()
xhr.open('post', 'http://localhost:3000/post')
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
params = "name=zs&age=12"
xhr.send(params)
xhr.onload = function () {
console.log(xhr.responseText);
}
</script> -->
<!-- 第二种使用json形式 -->
<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请求封装
<!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)
}
})
}
// 封装一个jsonP函数
function jsonP(e) {
var script = document.createElement('script')
// 将传递的data取出来
params = ''
for(let arr in e.data){
params+=`&${arr}=${e.data[arr]}`
}
// 设置window下的随机函数名
fName = 'myjson' + Math.random().toString().replace('.', '')
// 设置src中的请求地址
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>
app.get('/better',(req,res)=>{
// const fName = req.query.callback
// const result = fName + '({name:"zs"})'
// res.send(result)
res.jsonp({name:'zs',age:98})
})
腾讯天气API
<!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/hexofixed@v0.47/js/jquery-3.5.1.min.js"></script>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/Rr210/hexofixed@frame/frame/bootstrap/3/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/gh/Rr210/hexofixed@frame/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')
// 构造一个date函数
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) => {
// console.log(e);
let html = template('tpl', { info: e.data.forecast_1h })
// console.log(html);
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()
}
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
<!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.withCredentials = true
xhr.send()
xhr.onload = function () {
console.log(xhr.responseText);
}
}
</script>
</body>
</html>
app.post('/logins', (req, res) => {
// console.log(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 })
}
// res.send(fields)
})
// 解析formdata
})
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对象
<!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/hexofixed@v0.47/js/jquery-3.5.1.min.js"></script>
<script>
$('#form').on('submit', function () {
// let params = $("#form").serialize()
// console.log(params);
// return false;
serializeObject($(this))
return false
})
function serializeObject(obj) {
let result = {}
let params = obj.serializeArray()
// console.log(params)
$.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名称
<!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/hexofixed@v0.47/js/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">
发送请求
</button>
<script>
// $('#btn').on('click',function(){
// $.ajax({
// type:'get',
// url:'jsonp',
// success:(res)=>{
// console.log(res);
// }
// })
// })
$('#btn').on('click',function(){
$.ajax({
url:"/jsonp",
type:'get',
dataType:'jsonp',
success:(res)=>{
console.log(res);
}
})
})
</script>
</body>
</html>