文章目录
一、原生AJAX
1.1 ajax简介
AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。
通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
1.2 XML简介
XML:可扩展标记语言
XML作用:用来被传输和存储数据(html用来呈现数据)
XML和HTML类似,不同的是html都是预定义标签,而XML都是自定义标签
比如说我有一个学生数据:
name = “孙悟空” ; age = 18 ; gender = “男” ;
用 XML 表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
现在被JSON替换了
{"name":"孙悟空","age":18,"gender":"男"}
1.3 AJAX特点
1.3.1 ajax优点
1)可以无需刷新页面而与服务器端进行通信。
2)可以根据用户事件更新部分页面内容
1.3.2 ajax缺点
1)不利于SEO
2)存在跨域问题(同源)
3)没有浏览历史,不能回退
1.3.3知识点补充(服务器)
1)补充 http:
超文本传输协议:规定了浏览器与服务器端进行通信的规则协议。
请求报文:
请求行(请求方式+请求地址+http/1.1)
请求头(host+cookie+content-type+…)
2)补充nodejs安装:
点击下载之后根据提示进行安装。
3)补充express安装:
①打开终端,初始化:npm init --yes
②输入npm i express进行安装
4)express基本使用
// 引入express
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由规则
app.get('/',(request,reponse)=>{
reponse.send('hello express')
})
// 监听端口
app.listen(8000,()=>{
console.log("服务器已启动,8000端口正在响应中...")
})
结果:
1.4 AJAX基本使用
1.4.1 ajax发送GET请求基本操作
创建文件set.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>AJAX请求</title>
<style>
#result{
width: 100px;
height: 50px;
border: 1px solid skyblue;
}
</style>
</head>
<body>
<button>AJAX请求</button>
<div id="result"></div>
<script>
// 获取元素
var btn = document.getElementsByTagName("button")[0]
var result = document.getElementById('result')
// 绑定事件
btn.onclick = function(){
// 创建对象
var xhr = new XMLHttpRequest()
// 初始化。设置请求方法和地址
xhr.open('GET','http://127.0.0.1:8000/server')
// 发送
xhr.send()
// 事件绑定,处理服务端返回的结果
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status>=200&&xhr.status<300){
result.innerHTML = xhr.response
}
}
}
}
</script>
</body>
</html>
服务器端:
// 引入express
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由规则
app.get('/server',(request,reponse)=>{
reponse.setHeader('Access-Control-Allow-Origin','*')
reponse.send('hello ajax')
})
// 监听端口
app.listen(8000,()=>{
console.log("服务器已启动,8000端口正在响应中...")
})
点击按钮后结果:
思考:Get请求如何传递参数呢?
xhr.open('GET',http://127.0.0.1:8000/server?a=1&b=2&c=3),
1.4.2 ajax发送POST请求基本操作
创建post请求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>Document</title>
<style>
#result{
width: 100px;
height: 50px;
border: 1px solid rgb(228, 29, 175);
}
</style>
</head>
<body>
<div id="result"></div>
</body>
<script>
const result = document.getElementById('result')
result.addEventListener('mouseover',()=>{
// 创建对象
var xhr = new XMLHttpRequest()
// 初始化,设置请求方式、地址
xhr.open('POST','http://127.0.0.1:8000/server')
// 发送
xhr.send()
// 处理服务器返回的数据
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300){
result.innerHTML = xhr.response
}
}
}
})
</script>
</html>
创建server.js
// An highlighted block
// 引入express
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由规则
app.get('/server',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*')
response.send('hello ajax')
})
app.post('/server',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*')
response.send('hello ajax1')
})
// 监听端口
app.listen(8000,()=>{
console.log("服务器已启动,8000端口正在响应中...")
})
鼠标悬停结果:
那么,post请求如何传递参数呢?
浏览器可以看到:
1.4.3 ajax设置请求头信息
服务器端:
1.4.2 服务器端响应JSON信息
json.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>Document</title>
<style>
#result{
width: 100px;
height: 50px;
border: 1px solid pink;
}
</style>
</head>
<body>
<div id="result"></div>
</body>
<script>
var result = document.getElementById('result')
result.onmousedown = function(){
var xhr = new XMLHttpRequest()
// 1、设置响应体数据的类型为json,后xhr.response会自动转换为对象
xhr.responseType = 'json'
xhr.open('POST','http://127.0.0.1:8000/json-server')
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300){
result.innerHTML = xhr.response.name
}
}
}
}
</script>
</html>
方式二部分代码:
result.onmousedown = function(){
var xhr = new XMLHttpRequest()
// 1、设置响应体数据的类型为json,后xhr.response会自动转换为对象
// xhr.responseType = 'json'
xhr.open('POST','http://127.0.0.1:8000/json-server')
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300){
// result.innerHTML = xhr.response.name
// 手动设置JSON格式
result.innerHTML = JSON.parse(xhr.response).name
}
}
}
}
server.js部分代码:
app.post('/json-server',(request,response)=>{
const data = {
'name':'jiangya'
}
response.setHeader('Access-Control-Allow-Origin','*')
// send括号里面只能存放字符串格式的数据
response.send(JSON.stringify(data))
})
鼠标点击返回结果:
1.4.3 处理网络延时或错误
html部分代码:
<body>
<div id="result"></div>
</body>
<script>
var result = document.getElementById("result");
result.onmouseover = function () {
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8000/delay");
xhr.send();
xhr.timeout = 2000;
xhr.ontimeout = function () {
alert("网络异常,请稍后重试");
};
xhr.onerror = function () {
alert("网络错误,请检查网络状态");
};
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status < 300) {
}
}
};
};
</script>
server.js部分代码:
//延时设置
app.get('/delay',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*')
setTimeout(() => {
response.send('延时响应')
}, 3000);
})
鼠标悬停2s后结果显示:
网络错误:
1.4.4 手动取消请求
<body>
<button>请求数据</button>
<button>取消请求</button>
</body>
<script>
var btns = document.getElementsByTagName("button");
let xhr = null
btns[0].onclick = function () {
xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8000/delay");
xhr.send();
};
// abort
btns[1].onclick = function() {
xhr.abort()
}
</script>
1.4.4 请求重复发送问题
部分html代码:
<body>
<button>请求数据</button>
<button>取消请求</button>
</body>
<script>
var btns = document.getElementsByTagName("button");
let xhr = null
//判断是否正在请求标志
let isSending = false
btns[0].onclick = function () {
if(isSending) xhr.abort() //如果正在请求,则取消该请求,创建一个新的请求
isSending = true
xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8000/delay");
xhr.send();
xhr.onreadystatechange = function(){
if(readyState == 4){
isSending = false
}
}
};
// abort
btns[1].onclick = function() {
xhr.abort()
}
</script>
浏览器调试截图:
二、同源策略
什么是同源?
协议、域名、端口号完全相同
什么是跨域?
违背同源策略,就是跨域
2.1案例
index.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>
<body>
<button>获取数据</button>
</body>
<script>
var btn = document.getElementsByTagName('button')
btn[0].onclick = function(){
var xhr = new XMLHttpRequest()
// 满足同源策略,这里url可以简写
xhr.open('GET','/data')
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300){
alert(xhr.response)
}
}
}
}
</script>
</html>
server.js
var express = require('express')
var app = express()
app.get('/home',(request,response)=>{
response.sendFile(__dirname+"/index.html")
})
app.get('/data',(request,response)=>{
response.send('用户数据')
})
app.listen(9000,()=>{
console.log('9000端口正在运行中...')
})
在浏览器端地址栏输入端口号http://127.0.0.1:9000/home
点击按钮后
2.2 如何解决跨域
2.2.1 JSONP
1)什么是JSONP
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持 get 请求
2)JSONP是如何工作的
在网页有一些标签天生具有跨域能力,比如:img link iframe script。
JSONP 就是利用 script 标签的跨域能力来发送请求的。
3)JSONP的使用
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>JSONP</title>
<style>
#result{
width: 200px;
height: 100px;
border: 1px solid royalblue;
}
</style>
</head>
<body>
<div id="result"></div>
</body>
<script>
// 处理函数
function handle(str){
var result = document.getElementById('result')
result.innerHTML = str
}
</script>
<script src="http://127.0.0.1:8000/jsonp-server"></script>
</html>
server.js部分代码:
app.all('/jsonp-server',(request,response)=>{
response.end("handle('姜姜鸭')")
})
最后浏览器结果:
2.2.2 CORS
链接: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
1)什么是CORS
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
2)CORS 怎么工作的?
CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应,以后就会对响应放行
3)CORS的使用
response.setHeader('Access-Control-Allow-Origin','*')