AJAX知识点(前后端交互技术)
原生AJAX
AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML,通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无需刷新就可获取数据。
AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
XML简介
- XML可扩展标记语言。
- XML被设计用来传输和存储数据。HTML用来呈现数据。
- XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据
比如说有一个学生数据:
用XML表示<student><name>孙悟空</name><age>18</age><gender>男</gender></student>
XML目前已被JSON取代
AJAX的特点
AJAX的优点
- 可以无需刷新页面而与服务器端进行通信
- 允许你根据用户事件来更新部分页面内容
AJAX的缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO不友好(搜索引擎优化 )
JS动态创建数据,搜索引擎不能搜索到,不可通过爬虫找到关键信息
HTTP协议
HTTP(hypertext transport protocol)协议【超文本传输协议】,协议详细规定了浏览器和万维网服务器之间互相通信的规则。
请求报文
重点是格式与参数
行 POST /s?ie=utf-8 HTTP/1.1头 Host:atguigu.comCookie:name=guiguContent-type:application/x-www-form-urlencodedUser-Agent:chrome 83 空行体 username=admain&password=admin如果是GET请求,请求体是空的,如果是POST请求,请求体可以不为空
响应报文
行 HTTP/1.1(协议版本) 200(协议状态码) ok(协议字符串)头 Content-Type:text/html;charset=utf-8Content-length:2048Content-encoding:gzip空行体 <html><head><body><h1>尚硅谷</h1></body></head></html>
例如:在百度中搜索CSDN,点击F12键,点击Network刷新页面,之后点击第一个链接
点击之后会出现以下几个标签
Preview作为一个响应预览 ,展示解析之后的界面
Header标签中会展示以下页面
以上就包含了响应头(Response Headers)和请求头(Request Headers)
点击请求头之后会出现请求头的内容,但此时没有请求行,此时点击view source,就会出现请求行的内容
Header标签中的Query String Parameters为查询字符串,对请求行中的url进行解析
响应头同理
响应体在Response里
例如在进行登陆页面时,请求体在Form Data中,里面会包含用户输入的账号和密码等信息
Express基于Node.js平台,快速,开放,极简的Web开发框架
简单的express框架使用
//1.引入express
const express=require('express')
// 2.创建应用对象
const app=express()
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/',(request,response)=>{// 设置响应response.send('HELLO EXPRESS')
})
// 4.监听端口启动服务
app.listen(8000,()=>{console.log("服务已经启动,8000端口监听中.....")
})
运行此代码时终端效果如下:
8000端口则会显示出响应
以下为向响应器发出的请求头和请求行
响应头和响应行如下:
响应体
案例
需求:点击按钮,发送请求之后,将响应体的内容显示在页面上,页面不刷新
服务准备:
//1.引入express
const express=require('express')
// 2.创建应用对象
const app=express()
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 当客户端浏览器向服务端发送请求时,请求行的第二段路径是/server的话,就会执行回调函数里面的代码,并且由response来作出响应
app.get('/server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// 设置响应体response.send('HELLO AJAX')
})
// 4.监听端口启动服务
app.listen(8000,()=>{console.log("服务已经启动,8000端口监听中.....")
})
发送新的请求时,需将8000端口释放,否则终端会报错提示8000端口已被占用
故要先释放上一次端口,才可继续发送请求,在node终端中输入ctrl+c释放端口即可,node即为上次发送请求的终端,在此终端中输入ctrl+c即可
html以及js代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AJAX GET请求</title><style>#result{width: 200px;height: 100px;border: solid 1px #000;}</style>
</head>
<body><button>点击发送请求</button><div id="result"></div><script>// 获取button元素const btn=document.getElementsByTagName('button')[0]const result=document.getElementById('result')// 绑定事件btn.addEventListener('click',function(){// console.log('test')// 1.创建对象// XHR是对AJAX请求做出一个筛选const xhr=new XMLHttpRequest()// 2.初始化 设置请求方法和URLxhr.open('GET','http://127.0.0.1:8000/server')// 3.发送xhr.send()// 4.事件绑定 处理服务端返回的结果// on when 当.....时候// readystate 是对象中的属性,表示状态 // 0表示未初始化 1表示open方法已经调用完毕 2表示send方法已经调用完毕 3表示服务端返回的部分结果 4表示服务端返回的所有结果// change 改变// 该事件总共会触发四次 0-1一次 1-2一次 2-3一次 3-4一次xhr.onreadystatechange=function(){// 处理服务端返回的结果 当状态为4的时候处理,状态为4已经返回所有结果// 判断(服务端返回了所有的结果)if(xhr.readyState===4){// 判断响应状态码 200 404 401 500// 2XX 表示成功if(xhr.status>=200&&xhr.status<300){// 处理结果 行 头 空行 体// 1.响应行// console.log(xhr.status)//状态码// console.log(xhr.statusText)//状态字符串// console.log(xhr.getAllResponseHeaders())//获取所有响应头// console.log(xhr.response)//响应体// 设置result的文本result.innerHTML=xhr.response}else{}}}})</script>
</body>
</html>
在AJAX请求中如何设置url参数
在url地址后面添加?参数=参数值,多个参数中间用&隔开
http://127.0.0.1:8000/server?a=100&b=200&c=300
AJAX POST请求
向8000端口发送POST请求,原来的js代码只有get请求,故还要添加POST请求代码才可
app.post('/server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// 设置响应体response.send('HELLO AJAX POST')
})
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AJAXPOST请求</title><style>#result {width: 200px;height: 100px;border: solid 1px #903;}</style>
</head>
<body><div id="result"></div><script>// 获取元素对象const result=document.getElementById('result')result.addEventListener('mouseover',function(){// console.log("test")// 1.创建对象const xhr=new XMLHttpRequest()// 2.初始化 设置类型与URLxhr.open('POST','http://127.0.0.1:8000/server')// 3.发送xhr.send()// 4.事件绑定xhr.onreadystatechange=function(){if(xhr.readyState===4){if(xhr.status>=200&&xhr.status<300){// 处理服务器返回的结果result.innerHTML=xhr.response}}}})</script>
</body>
</html>
//1.引入express
const express=require('express')
// 2.创建应用对象
const app=express()
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 当客户端浏览器向服务端发送请求时,请求行的第二段路径是/server的话,就会执行回调函数里面的代码,并且由response来作出响应
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 AJAX POST')
})
// 4.监听端口启动服务
app.listen(8000,()=>{console.log("服务已经启动,8000端口监听中.....")
})
POST传递参数
在send中传入参数
xhr.send('a=100&b=200&c=300')或xhr.send('a:100&b:200&c:300')
在AJAX中设置请求头信息
在初始化open之后添加如下代码
// Content-Type设置请求体内容的类型// application/x-www-form-urllencoded参数查询字符串类型xhr.setRequestHeader('Content-Type','application/x-www-form-urllencoded')
设置自定义请求头
app.all('/server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// 响应头response.setHeader('Access-Control-Allow-Headers','*') // '*'表示所有头信息都可以接受// 设置响应体response.send('HELLO AJAX POST')
})
将post改为all,表示可以接收任意类型的请求(get post options等)
xhr.setRequestHeader('name','atguigu')
实现POST请求完整代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AJAXPOST请求</title><style>#result {width: 200px;height: 100px;border: solid 1px #903;}</style>
</head>
<body><div id="result"></div><script>// 获取元素对象const result=document.getElementById('result')result.addEventListener('mouseover',function(){// console.log("test")// 1.创建对象const xhr=new XMLHttpRequest()// 2.初始化 设置类型与URLxhr.open('POST','http://127.0.0.1:8000/server')// 设置请求头// Content-Type设置请求体内容的类型// application/x-www-form-urllencoded参数查询字符串类型xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')xhr.setRequestHeader('name','atguigu')// 3.发送xhr.send('a=100&b=200&c=300')// xhr.send('a:100&b:200&c:300')// 4.事件绑定xhr.onreadystatechange=function(){if(xhr.readyState===4){if(xhr.status>=200&&xhr.status<300){// 处理服务器返回的结果result.innerHTML=xhr.response}}}})</script>
</body>
</html>
//1.引入express
const express=require('express')
// 2.创建应用对象
const app=express()
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 当客户端浏览器向服务端发送请求时,请求行的第二段路径是/server的话,就会执行回调函数里面的代码,并且由response来作出响应
app.get('/server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// 设置响应体response.send('HELLO AJAX')
})
// all表示可以接收任意类型的请求(get post options等)
app.all('/server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// 响应头response.setHeader('Access-Control-Allow-Headers','*') // '*'表示所有头信息都可以接受// 设置响应体response.send('HELLO AJAX POST')
})
// 4.监听端口启动服务
app.listen(8000,()=>{console.log("服务已经启动,8000端口监听中.....")
})
JSON数据的响应以及前端代码的处理
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#result{width: 200px;height: 100px;border: solid 1px #89b;}</style>
</head>
<body><div id="result"></div><script>const result=document.getElementById('result')// 绑定键盘按下事件window.onkeydown=function(){// 发送请求const xhr=new XMLHttpRequest()// 设置响应体数据的类型xhr.responseType='json'// 初始化xhr.open('GET','http://127.0.0.1:8000/json-server')xhr.send()xhr.onreadystatechange=function(){if(xhr.readyState===4){if(xhr.status>=200&&xhr.status<300){// console.log(xhr.response)// result.innerHTML=xhr.response// 1.手动对数据进行转换// let data=JSON.parse(xhr.response)// console.log(data)// 2.自动转换xhr.responseType='json'result.innerHTML=xhr.response.name}}}}</script>
</body>
</html>
//1.引入express
const express=require('express')
// 2.创建应用对象
const app=express()
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 当客户端浏览器向服务端发送请求时,请求行的第二段路径是/server的话,就会执行回调函数里面的代码,并且由response来作出响应
app.get('/server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// 设置响应体response.send('HELLO AJAX')
})
// all表示可以接收任意类型的请求(get post options等)
app.all('/json-server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// 响应头response.setHeader('Access-Control-Allow-Headers','*') // '*'表示所有头信息都可以接受// 响应一个数据const data={name:'atguigu'}// 对对象进行字符串转换let str=JSON.stringify(data)// 设置响应体response.send(str)//里面只能接收字符串或者buffer(保存二进制文件数据)
})
// 4.监听端口启动服务
app.listen(8000,()=>{console.log("服务已经启动,8000端口监听中.....")
})
nodemon重新启动
在终端运行服务器代码时输入nodemon.cmd xxx.js,当服务器js代码改变时,会自动重新启动,不用手动启动
IE浏览器缓存问题
IE浏览器会对AJAX请求结果进行缓存,在下次进行请求时是从本地缓存中获取,而不是服务器返回的最新数据,对于时效性比较强的场景,AJAX缓存不能及时显示,会影响结果
解决方法:
xhr.open('GET','http://127.0.0.1:8000/ie?t='+Date.now())
请求超时与网络异常
项目向服务器请求时,不能保证服务端能够及时快速的响应,这时就会请求超时,同时,在网络异常时,也需要给用户一个提醒
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>IE缓存问题</title><style>#result {width: 200px;height: 100px;border: solid 1px #258;}</style>
</head>
<body><button>点击发送请求</button><div id="result"></div><script>const btn=document.getElementsByTagName('button')[0]const result=document.querySelector('#result')btn.addEventListener('click',function(){// console.log('test')const xhr=new XMLHttpRequest()// 超时设置2s设置xhr.timeout=2000//2s之后若没有成功返回结果就取消// 超时回调xhr.ontimeout=function(){alert("网络异常,请稍后重试!!")}// 网络异常回调xhr.onerror=function(){alert('你的网络似乎出了一些问题!')}xhr.open('GET','http://127.0.0.1:8000/delay')xhr.send()xhr.onreadystatechange=function(){if(xhr.readyState===4){if(xhr.status>=200&&xhr.status<300){result.innerHTML=xhr.response}}}})</script>
</body>
</html>
app.get('/delay',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')setTimeout(()=>{response.send('延时响应')},3000)// 设置响应体})
手动取消请求
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>取消请求</title>
</head>
<body><button>点击发送</button><button>点击取消</button><script>// 获取元素对象const btns=document.querySelectorAll('button')let x=nullbtns[0].onclick=function(){x=new XMLHttpRequest()x.open('GET','http://127.0.0.1:8000/delay')x.send()}// abortbtns[1].onclick=function(){x.abort()}</script>
</body>
</html>
重复请求问题
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>重复请求</title>
</head>
<body><button>点击发送</button><button>点击取消</button><script>// 获取元素对象const btns=document.querySelectorAll('button')let x=null// 标识变量let isSending=false//是否正在发送AJAX请求btns[0].onclick=function(){if(isSending)x.abort()//如果正在发送,则取消该请求,创建一个新的请求x=new XMLHttpRequest()isSending=truex.open('GET','http://127.0.0.1:8000/delay')x.send()x.onreadystatechange=function(){if(x.readyState===4){// 修改标识变量isSending=false}}}// abortbtns[1].onclick=function(){x.abort()}</script>
</body>
</html>
jQuery中的AJAX
get请求
$.get(url,[data],[callback],[type])
url:请求的URL地址
data:请求携带的参数
callback:载入成功时回调函数
type:设置返回内容的格式,xml,html,script,json,text,_default
post请求
$.post(url,[data],[callback],[type])
url:请求的URL地址
data:请求携带的参数
callback:载入成功时回调函数
引入jquery.js文件
搜索BootCDN官网
之后搜索jquery,点击jquery后选择所需版本并复制script标签,将其放置在html里即可
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="../bootstrap-3.3.2-dist/css/bootstrap-theme.css"><link rel="stylesheet" href="../bootstrap-3.3.2-dist/css/bootstrap.css"><link rel="stylesheet" href="../bootstrap-3.3.2-dist/css/bootstrap.min.css"><title>jQuery发送AJAX请求</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
</head>
<body><div class="container"><h2 class="page-header">jQuery发送AJAX请求</h2><button class="btn btn-primary">GET</button><button class="btn btn-danger">POST</button><button class="btn btn-info">通用型方法ajax</button></div><script>$('button').eq(0).click(function(){$.get('http://127.0.0.1:8000/jquery-server',{a:100,b:200},function(data){console.log(data)},'json')//第一个参数给谁发,第二个为传进去的参数//第三个为回调函数,data为响应体第四个参数为响应体类型})$('button').eq(1).click(function(){$.post('http://127.0.0.1:8000/jquery-server',{a:100,b:200},function(data){console.log(data)})//第一个参数给谁发,第二个为传进去的参数//第三个为回调函数,data为响应体})</script>
</body>
</html>
// jQuery服务
app.all('/jquery-server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin','*')// response.send('Hello jQuery AJAX')const data={name:'尚硅谷'}response.send(JSON.stringify(data))
})
get请求第四个参数表示响应体类型,上述代码在进行get请求时,其返回结果类型为json,而post请求返回的结果只是字符串
$.ajax方法接收的参数是一个对象,包括url,参数,请求类型,成功的回调以及响应体结果的类型等等
$('button').eq(2).click(function(){$.ajax({//urlurl:'http://127.0.0.1:8000/delay',// 参数data:{a:100,b:200},// 请求类型type:'GET',// 响应体结果类型dataType:'json',// 成功的回调success:function(data){console.log(data)},// 超时时间timeout:2000,// 失败的回调error:function(){console.log('出错啦!!!')},// 头信息headers:{c:300,d:400}})})
crossorigin="anonymous"
crossorigin="anonymous"
是一个HTML属性,用于设置图像、脚本、样式表等外部资源的跨源资源共享(Cross-Origin Resource Sharing,简称 CORS)策略。当将其应用于如<img>
,<script>
,<link rel="stylesheet">
等标签时,它的作用主要是:
允许跨域加载资源:在默认情况下,浏览器实施同源策略(Same-origin policy),阻止从一个域名加载的网页脚本访问来自不同源的资源。通过设置
crossorigin="anonymous"
,你可以告诉浏览器允许请求的资源来自不同的源,并且请求应该带有一个匿名的凭据标志,表示请求不应包含 cookies 或 HTTP 认证信息。控制请求头的信息:当使用
crossorigin="anonymous"
时,浏览器会在请求头中添加一个Origin
字段,告知服务器这个请求是跨域的。服务器需要配置相应的CORS headers(如Access-Control-Allow-Origin
)来允许这种跨域请求。如果服务器允许,它将在响应头中返回Access-Control-Allow-Origin
,从而使得浏览器能够成功接收并使用这个跨域资源。无凭据请求:特别需要注意的是,
anonymous
模式下,请求不会发送cookie或其他认证信息,这与使用withCredentials
属性发送凭据的请求(通常用于Ajax请求)不同。这对于那些不需要用户特定信息的公共资源加载非常有用,提高了安全性,因为减少了信息泄露的风险。总之,
crossorigin="anonymous"
主要用于实现安全地跨域加载脚本、样式和图像等静态资源,而不涉及用户的认证信息,是一种提高Web应用安全性和灵活性的机制。
Axios发送AJAX请求
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.6.8/axios.js"></script><title>axios 发送AJAX请求</title>
</head>
<body><button>GET</button><button>POST</button><button>AJAX</button><script>const btns=document.querySelectorAll('button')// 配置baseURLaxios.defaults.baseURL='http://127.0.0.1:8000'btns[0].onclick=function(){// GET请求axios.get('/axios-server',{// url参数params:{id:100,vip:7},// 请求头信息Headers:{name:'atguigu',age:20}}).then(value=>{//对返回结果进行处理,与jquery的回调函数的作用相似console.log(value)})}btns[1].onclick=function(){axios.post('/axios-server',// 请求体{username:'admin',password:'admin'},{// urlparams:{id:200,vip:9},// 请求头参数Headers:{weight:180,height:180}})}</script>
</body>
</html>
服务端代码:
// axios服务
app.all('/axios-server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Headers','*') // '*'表示所有头信息都可以接受response.setHeader('Access-Control-Allow-Origin','*')// response.send('Hello jQuery AJAX')const data={name:'尚硅谷'}response.send(JSON.stringify(data))
})
axios通用方法发送请求
btns[2].onclick=function(){axios({// 请求方法method:'POST',// urlurl:'/axios-server',// url参数params:{vip:10,level:30},// 头信息headers:{a:100,b:200},// 请求体参数data:{username:'admin',password:'admin'}}).then(response=>{console.log(response)// 响应状态码console.log(response.status)// 响应状态字符串console.log(response.statusText)// 响应头信息console.log(response.headers)// 响应体console.log(response.data)})}
fetch发送AJAX请求
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>fetch 发送 AJAX请求</title>
</head>
<body><button>AJAX请求</button><script>const btn=document.querySelector('button')btn.onclick=function(){//接收两个参数,第一个为url,第二个为可选配置对象fetch('http://127.0.0.1:8000/fetch-server?vip=10',{// 请求方法method:'POST',// 请求头headers:{name:'atguigu'},body:'username=admin&password=admin'}).then(response=>{// console.log(response)// return response.text()return response.json()//把数据转化成json对象}).then(response=>{console.log(response)})}</script>
</body>
</html>
服务端代码:
// fetch服务
app.all('/fetch-server',(request,response)=>{// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Headers','*') // '*'表示所有头信息都可以接受response.setHeader('Access-Control-Allow-Origin','*')// response.send('Hello jQuery AJAX')const data={name:'尚硅谷'}response.send(JSON.stringify(data))
})
同源策略
同源策略是浏览器的一种安全策略
同源:当前网页的url和AJAX请求的目标资源的url的协议,域名,端口号必须完全相同
AJAX默认遵从同源策略,违背同源策略就是跨域
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>首页</title>
</head>
<body><h1>尚硅谷</h1><button>点击获取用户数据</button><script>const btn=document.querySelector('button')btn.onclick=function(){const x=new XMLHttpRequest()// 因为满足同源策略 所以url可以简写x.open("GET",'/data')// 发送x.send()x.onreadystatechange=function(){if(x.readyState===4){if(x.status>=200&&x.status<300){console.log(x.response)}}}}</script>
</body>
</html>
const express=require('express')
const app=express()
app.get('/home',(request,response)=>{// 响应一个页面response.sendFile(__dirname+'/index.html')//__dirname在node中是当前文件的绝对路径})
app.get('/data',(request,response)=>{response.send('用户数据')
})
app.listen(9000,()=>{console.log("服务已经启动...")
})
在网址中输入127.0.0.1:9000/home即可进入首页页面
如何解决跨域
JSONP
JSONP是什么?
JSONP,是一个官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求
JSONP是怎么工作的?
在网页有一些标签具有跨域能力,比如:img,link,iframe,script
JSONP就是利用script标签的跨域能力来发送请求的
JSONP的使用
1.动态的创建一个script标签
var script=document.creatElement("script")
2.设置script的src,设置回调函数
script.src="http://localhost:3000/testAJAX?callback=abc"
原理实现
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>原理演示</title><style>#result{width: 300px;height: 100px;border: solid 1px #78a;}</style>
</head>
<body><div id="result"></div><script>function handle(data){// 获取result元素const result=document.getElementById('result')result.innerHTML=data.name
}</script><!-- <script src="./js/app.js"></script> --><!-- <script src="http://127.0.0.1:5500/%E8%B7%A8%E5%9F%9F/JSONP/%E5%8E%9F%E7%90%86.html"></script> --><script src="http://127.0.0.1:8000/jsonp-server"></script> <!-- script发送请求应该返回标准的js代码 --></body>
</html>
app.js
const data={name:'尚硅谷'
}
console.log(data)
// function handle(data){
// // 获取result元素
// const result=document.getElementById('result')
// result.innerHTML=data.name
// }
handle(data)
8000端口:
// jsonp服务
app.all('/jsonp-server',(request,response)=>{// response.send('console.log("hello jsonp-server")')const data={name:'尚硅谷'}// 将数据转化为字符串let str=JSON.stringify(data)// 返回结果response.end(`handle(${str})`)//end不会加特殊响应头
})
原生JSONP的实现
案例:用户注册输入用户名后,当光标失去焦点时,向服务端发送请求,服务端返回是否存在该用户名,存在就将input框变成红色
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>案例</title>
</head>
<body>用户名: <input type="text" id="username"><p></p><script>// 获取input元素const input=document.querySelector('input')const p=document.querySelector('p')// 声明handle函数function handle(data){input.style.border="solid 1px #f00"p.innerHTML=data.msg}// 绑定事件input.onblur=function(){// 获取用户的输入值let username=this.value// 向服务器端发送请求 检测用户名是否存在// 1.创建标签的src属性const script=document.createElement('script')// 2.设置标签的src属性script.src='http://127.0.0.1:8000/check-username'document.body.appendChild(script)}</script>
</body>
</html>
// 检测用户名是否存在
app.all('/check-username',(request,response)=>{// response.send('console.log("hello jsonp-server")')const data={exist:1,msg:'用户名已经存在'}// 将数据转化为字符串let str=JSON.stringify(data)// 返回结果response.end(`handle(${str})`)//end不会加特殊响应头
})
用jQuery发送jsonp请求
点击按钮,向8000端口发送jsonp请求,将返回结果放置在result中
$.getJSON()
是 jQuery 库中的一个函数,用于简化 AJAX 请求,专门用于获取 JSON 格式的数据。这个函数是$.ajax()
的一个便捷封装,用于执行 HTTP GET 请求,并自动将返回的数据解析为 JavaScript 对象(即 JSON 格式数据)。使用
$.getJSON()
的基本语法如下:$.getJSON(url, data, function(data) {// 这个函数会在请求成功并且数据被解析后执行// "data" 参数包含了从服务器返回的 JSON 数据,已经被转换成 JavaScript 对象console.log(data); }).done(function() {// 可选的,当请求成功完成时执行 }).fail(function(jqXHR, textStatus, errorThrown) {// 可选的,当请求失败时执行 }).always(function() {// 可选的,无论请求成功或失败都会执行 });
- url: (字符串)必需,规定要发送请求的 URL。
- data: (可选,对象或字符串)发送到服务器的数据,可以是对象的键值对或查询字符串形式。
- callback: (函数)当请求成功,并且服务器返回了数据时,会执行这个函数。返回的数据会作为参数传递给这个函数。
.done()
,.fail()
,.always()
方法提供了对成功、失败和完成状态的回调处理,增加了请求的灵活性。请注意,由于 jQuery 是一个库,所以在使用
$.getJSON()
之前,确保已经在项目中引入了 jQuery。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery-jsonp</title><style>#result {width: 300px;height: 100px;border: solid 1px #089;}</style><script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body><button>点击发送jsonp请求</button><div id="result"></div><script>$('button').eq(0).click(function(){$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?',function(data){// console.log(data)$('#result').html(`名称:${data.name}<br>校区:${data.city}`)})})</script>
</body>
</html>
// 用jQuery发送jsonp请求
app.all('/jquery-jsonp-server',(request,response)=>{// response.send('console.log("hello jsonp-server")')const data={name:'尚硅谷',city:['北京','上海','深圳']}// 将数据转化为字符串let str=JSON.stringify(data)// 接收callback参数let cb=request.query.callback//接收callback返回的参数// 返回结果response.end(`${cb}(${str})`)//end不会加特殊响应头
})
CORS
CORS是什么?
CORS,跨域资源共享,CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求,跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权访问哪些资源
CORS是怎么工作的
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
CORS的使用
主要是服务器端的设置:
router.get("/testAJAX",function(req,res){})
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><button>发送请求</button><div id="result"></div><script>const btn=document.querySelector('button')btn.onclick=function(){// 1.创建对象const x=new XMLHttpRequest()// 2.初始化位置x.open("GET",'http://127.0.0.1:8000/cors-server')// 3.发送x.send()// 4.绑定事件x.onreadystatechange=function(){if(x.readyState===4){if(x.status>=200&&x.status<300){// 输出响应体console.log(x,response)}}}}</script>
</body>
</html>
// cros
app.all('/cors-server',(request,response)=>{//设置响应头response.setHeader('Access-Control-Allow-Origin','*')response.setHeader('Access-Control-Allow-Headers','*')response.setHeader('Access-Control-Allow-Method','*')//客户端在发送请求时,跨域页面哪个都行,头信息和请求方法都随意// response.setHeader('Access-Control-Allow-Orign','http://127.0.0.1:5500')//只有http://只有127.0.0.1:5500端口的网页才可向该服务器发生请求response.send('hello CORS')
})
相关文章:

AJAX知识点(前后端交互技术)
原生AJAX AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML,通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无需刷新就可获取数据。 AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式 …...
用wordpress为外贸进出口公司搭建多语言国际站
使用WordPress为外贸进出口公司搭建多语言国际站是一个很好的选择,因为WordPress不仅易于使用,而且具有丰富的插件和主题,可以支持多语言内容。以下是搭建多语言国际站的步骤和建议: 安装WordPress:首先,您…...
雷军-2022.8小米创业思考-6-互联网七字诀之口碑:口碑即定位,超预期才有口碑,品牌建设
第六章 互联网七字诀 专注、极致、口碑、快,这就是我总结的互联网七字诀,也是我对互联网思维的高度概括。 口碑 用户口碑是所有产品成功的关键因素,这是不言而喻的公理。 资源永远有限,对于创业公司尤其如此。只有专注…...
欧盟MDR法规对医疗器械网络安全都有哪些要求?
MDR,欧盟医疗器械法规(Medical Device REGULATION (EU) 2017/745,简称“MDR”),当医疗器械办理欧盟CE认证时,需满足新法规 MDR (EU) 2017/745要求。 M DR符合性评估 医械网络安全咨询与相关文件出具&#x…...

Linux —— 信号初识
Linux —— 信号初识 什么是信号测试几个信号signal函数函数原型参数说明返回值注意事项示例 后台程序前台转后台检测输入中断向量表 我们今天来继续学习Linux的内容,今天我们要了解的是Linux操作系统中的信号: 什么是信号 信号是操作系统内核与进程之…...
webpack进阶 -- 自定义Plugin,Loader封装打包优化
介绍 Webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。在 Webpack 处理应用程序时,它会在内部构建一个依赖图(dependency graph),这个依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。在这个过程中…...

《Decoupled Optimisation for Long-Tailed Visual Recognition》阅读笔记
论文标题 《Decoupled Optimisation for Long-Tailed Visual Recognition》 长尾视觉识别的解耦优化 作者 Cong Cong、Shiyu Xuan、Sidong Liu、Shiliang Zhang、Maurice Pagnucco 和 Yang Song、 来自新南威尔士大学计算机科学与工程学院、北京大学计算机学院多媒体信息处…...

Springboot+Vue项目-基于Java+MySQL的毕业就业信息管理系统(附源码+演示视频+LW)
大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…...

条件平差——以水准网平差为例 (python详细过程版)
目录 一、原理概述二、案例分析三、代码实现四、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、原理概述 条件平差的函数模型和随机模型为: A V + W = 0...
mysql -- WITH RECURSIVE 语法
引言 在 SQL 中,WITH RECURSIVE 是一个用于创建递归查询的语句。它允许你定义一个 Common Table Expression (CTE),该 CTE 可以引用自身的输出。递归 CTE 非常适合于查询具有层次结构或树状结构的数据,例如组织结构、文件系统或任何其他具有…...

洗地机什么品牌好?洗地机怎么选?618洗地机选购指南
随着科技的飞速发展,洗地机以其高效的清洁能力、稳定的性能和用户友好的设计而闻名,不仅可以高效吸尘、拖地,还不用手动洗滚布,已经逐渐成为现代家庭不可或缺的清洁助手。然而,在众多品牌和型号中,如何选择…...
nginx负载均衡配置
1.nginx负载均衡配置 upstream lbs {server 192.168.1.12:8080;server 192.168.1.12:8081; }server {listen 80;server_name localhost a.com;#charset koi8-r;#access_log logs/host.access.log main;location / {root html;index index.html index.htm;}locatio…...

HarmonyOS NEXT星河版之美团外卖点餐功能实战(中)
接上 一、UI布局 1.1 购物车Item Preview Component export struct MTCartItemView {build() {Row({ space: 6 }) {Image(https://bkimg.cdn.bcebos.com/pic/4d086e061d950a7bc94a331704d162d9f3d3c9e2).width(42).aspectRatio(1).borderRadius(5)Column({ space: 3 }) {Text…...

CTF-Web Exploitation(持续更新)
CTF-Web Exploitation 1. GET aHEAD Find the flag being held on this server to get ahead of the competition Hints Check out tools like Burpsuite to modify your requests and look at the responses 根据提示使用不同的请求方式得到response可能会得到结果 使用…...
图书管理系统c语言
创建一个图书管理系统是一个涉及数据结构和文件操作的项目。在C语言中,你可以使用结构体来表示图书信息,使用函数来实现系统的各项功能。以下是一个简单的图书管理系统的示例,包括基本的添加、显示、查找和删除图书的功能。 1. 定义图书结构…...

森林消防—高扬程水泵,高效、稳定、可靠!/恒峰智慧科技
森林,作为地球的“绿色肺叶”,不仅为我们提供了丰富的自然资源,更是维持生态平衡的重要一环。然而,随着全球气候的变化和人为活动的增加,森林火灾频发,给生态环境和人民生命财产安全带来了巨大威胁。在森林…...

光伏设备制造5G智能工厂数字孪生可视化平台,推进行业数字化转型
光伏设备制造5G智能工厂数字孪生可视化平台,推进行业数字化转型。光伏设备制造5G智能工厂数字孪生可视化平台是光伏行业数字化转型的重要一环。通过数字孪生平台,光伏设备制造企业可以实现对生产过程的全面监控和智能管理,提高生产效率&#…...

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series
【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series 摘要 这段文字介绍了一个名为TS2Vec的通用框架,用于学习时间序列数据的表示,可以在任意语义层次上进行。与现有方法不同,TS2Vec通过对增强的上下文视图进行层次化…...
windows驱动开发-DMA技术(一)
DMA(Direct Memory Access)是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依于 CPU 的大量中断负载,否则CPU 需要从设备缓存中把每一页的数据复制到缓存中,然后把它们再次写入到新的地方,在这个过…...
实用的Chrome命令
以下是一些实用的Chrome命令及其用途: --allow-outdated-plugins:允许浏览器使用过期的插件,这在开发过程中可能会用到,以便测试兼容性。chrome://downloads:打开Chrome的下载页面,查看和管理你的下载文件…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...