当前位置: 首页 > news >正文

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的优点

  1. 可以无需刷新页面而与服务器端进行通信
  2. 允许你根据用户事件来更新部分页面内容

AJAX的缺点

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. 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"> 等标签时,它的作用主要是:

  1. 允许跨域加载资源:在默认情况下,浏览器实施同源策略(Same-origin policy),阻止从一个域名加载的网页脚本访问来自不同源的资源。通过设置 crossorigin="anonymous",你可以告诉浏览器允许请求的资源来自不同的源,并且请求应该带有一个匿名的凭据标志,表示请求不应包含 cookies 或 HTTP 认证信息。

  2. 控制请求头的信息:当使用 crossorigin="anonymous" 时,浏览器会在请求头中添加一个 Origin 字段,告知服务器这个请求是跨域的。服务器需要配置相应的CORS headers(如 Access-Control-Allow-Origin)来允许这种跨域请求。如果服务器允许,它将在响应头中返回 Access-Control-Allow-Origin,从而使得浏览器能够成功接收并使用这个跨域资源。

  3. 无凭据请求:特别需要注意的是,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&#xff0c;通过AJAX可以在浏览器中向服务器发送异步请求&#xff0c;最大的优势&#xff1a;无需刷新就可获取数据。 AJAX不是新的编程语言&#xff0c;而是一种将现有的标准组合在一起使用的新方式 …...

用wordpress为外贸进出口公司搭建多语言国际站

使用WordPress为外贸进出口公司搭建多语言国际站是一个很好的选择&#xff0c;因为WordPress不仅易于使用&#xff0c;而且具有丰富的插件和主题&#xff0c;可以支持多语言内容。以下是搭建多语言国际站的步骤和建议&#xff1a; 安装WordPress&#xff1a;首先&#xff0c;您…...

雷军-2022.8小米创业思考-6-互联网七字诀之口碑:口碑即定位,超预期才有口碑,品牌建设

第六章 互联网七字诀 专注、极致、口碑、快&#xff0c;这就是我总结的互联网七字诀&#xff0c;也是我对互联网思维的高度概括。 口碑 用户口碑是所有产品成功的关键因素&#xff0c;这是不言而喻的公理。 资源永远有限&#xff0c;对于创业公司尤其如此。只有专注&#xf…...

欧盟MDR法规对医疗器械网络安全都有哪些要求?

MDR&#xff0c;欧盟医疗器械法规&#xff08;Medical Device REGULATION (EU) 2017/745&#xff0c;简称“MDR”&#xff09;&#xff0c;当医疗器械办理欧盟CE认证时&#xff0c;需满足新法规 MDR (EU) 2017/745要求。 M DR符合性评估 医械网络安全咨询与相关文件出具&#x…...

Linux —— 信号初识

Linux —— 信号初识 什么是信号测试几个信号signal函数函数原型参数说明返回值注意事项示例 后台程序前台转后台检测输入中断向量表 我们今天来继续学习Linux的内容&#xff0c;今天我们要了解的是Linux操作系统中的信号&#xff1a; 什么是信号 信号是操作系统内核与进程之…...

webpack进阶 -- 自定义Plugin,Loader封装打包优化

介绍 Webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。在 Webpack 处理应用程序时&#xff0c;它会在内部构建一个依赖图(dependency graph)&#xff0c;这个依赖图对应映射到项目所需的每个模块&#xff0c;并生成一个或多个 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)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…...

条件平差——以水准网平差为例 (python详细过程版)

目录 一、原理概述二、案例分析三、代码实现四、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、原理概述 条件平差的函数模型和随机模型为: A V + W = 0...

mysql -- WITH RECURSIVE 语法

引言 在 SQL 中&#xff0c;WITH RECURSIVE 是一个用于创建递归查询的语句。它允许你定义一个 Common Table Expression (CTE)&#xff0c;该 CTE 可以引用自身的输出。递归 CTE 非常适合于查询具有层次结构或树状结构的数据&#xff0c;例如组织结构、文件系统或任何其他具有…...

洗地机什么品牌好?洗地机怎么选?618洗地机选购指南

随着科技的飞速发展&#xff0c;洗地机以其高效的清洁能力、稳定的性能和用户友好的设计而闻名&#xff0c;不仅可以高效吸尘、拖地&#xff0c;还不用手动洗滚布&#xff0c;已经逐渐成为现代家庭不可或缺的清洁助手。然而&#xff0c;在众多品牌和型号中&#xff0c;如何选择…...

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语言中&#xff0c;你可以使用结构体来表示图书信息&#xff0c;使用函数来实现系统的各项功能。以下是一个简单的图书管理系统的示例&#xff0c;包括基本的添加、显示、查找和删除图书的功能。 1. 定义图书结构…...

森林消防—高扬程水泵,高效、稳定、可靠!/恒峰智慧科技

森林&#xff0c;作为地球的“绿色肺叶”&#xff0c;不仅为我们提供了丰富的自然资源&#xff0c;更是维持生态平衡的重要一环。然而&#xff0c;随着全球气候的变化和人为活动的增加&#xff0c;森林火灾频发&#xff0c;给生态环境和人民生命财产安全带来了巨大威胁。在森林…...

光伏设备制造5G智能工厂数字孪生可视化平台,推进行业数字化转型

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

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series 摘要 这段文字介绍了一个名为TS2Vec的通用框架&#xff0c;用于学习时间序列数据的表示&#xff0c;可以在任意语义层次上进行。与现有方法不同&#xff0c;TS2Vec通过对增强的上下文视图进行层次化…...

windows驱动开发-DMA技术(一)

DMA(Direct Memory Access)是所有现代电脑的重要特色&#xff0c;它允许不同速度的硬件装置来沟通&#xff0c;而不需要依于 CPU 的大量中断负载&#xff0c;否则CPU 需要从设备缓存中把每一页的数据复制到缓存中&#xff0c;然后把它们再次写入到新的地方&#xff0c;在这个过…...

实用的Chrome命令

以下是一些实用的Chrome命令及其用途&#xff1a; --allow-outdated-plugins&#xff1a;允许浏览器使用过期的插件&#xff0c;这在开发过程中可能会用到&#xff0c;以便测试兼容性。chrome://downloads&#xff1a;打开Chrome的下载页面&#xff0c;查看和管理你的下载文件…...

数据库(MySQL)基础:约束

一、概述 1.概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 2.目的&#xff1a;保证数据库中数据的正确、有效性和完整性。 3.分类 约束描述关键字非空约束限制该字段的数据不能为nullnot null唯一约束保证该字段的所有数据都是唯一…...

ControlNet作者放大招!IC-Light:控制生成图片光照效果!

ControlNet作者张吕敏近日又开源了一项新的工作&#xff1a;IC-Light &#xff08;Impose Constant Light&#xff09;&#xff0c;在不改变图片内容的条件下&#xff0c;可以控制生成图片的光照效果。 作者发布了两种类型的模型&#xff1a;文本条件重打光模型和背景条件重打光…...

【Java】Java中类的初始化顺序(静态方法,静态块,非静态块,最后有流程图)

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、无继承关系类的初始化 1、静态变量k被初始化 2、静态变量t1初始化 3、静态变量 t2初始化 4、静态变量i初始化 5、静态变量n初始化 6、静态块初始化 7、非静态块初始化 8、非静态属性初始化 9、执行构造…...

在RK3588开发板使用FFMpeg 结合云服务器加SRS实现摄像头数据推流到云端拱其他设备查看

今天测试了一把在开发板把摄像头数据推流到云端服务器&#xff0c;然后给其他电脑通过val软件拉取显示摄像头画面&#xff0c;浅浅记录一下大概步骤 1.开发板端先下载ffmpeg apt install ffmpeg2.云服务器先安装SRS的库 云服务器我使用ubuntu系统&#xff0c;SRS是个什么东西&…...

elasticsearch搭建教程

主要参看这里就行,需要特别注意其中报错的解决方案&#xff1a;搭建elasticsearch 单机节点里&#xff0c;按照上述教程搭建只能开放本地访问&#xff0c;如果需要其他机器访问&#xff0c;需要在elasticsearch.yml里新增几个配置&#xff1a; node.name: node-1 network.host…...

c++ 归并排序

归并排序是一种遵循分而治之方法的排序算法。它的工作原理是递归地将输入数组划分为较小的子数组并对这些子数组进行排序&#xff0c;然后将它们合并在一起以获得排序后的数组。 简单来说&#xff0c;归并排序的过程就是将数组分成两半&#xff0c;对每一半进行排序&#xff0c…...

基于vs和C#的WPF应用之动画3

注&#xff1a;1、在内部和外部使用缓动函数 <Grid.Resources> <PowerEase x:Key"powerease" Power"3" EasingMode"EaseInOut"/> </Grid.Resources> <DoubleAnimation EasingFunction"{StaticResource powerease}&quo…...

Python import 必看技巧:打造干净利落的代码结构

大家好,学习Python你肯定绕不过一个概念import,它是连接不同模块的桥梁,是实现代码复用和模块化的关键。本文将带你深入探索Python中import的原理,并分享一些实用的导入技巧。 1. import 原理 导入机制概述 在Python中,模块(module)是一种封装Python代码的方式,它允许…...

计算机视觉(CV)(Computer Vision)

计算机视觉技术&#xff08;Computer Vision&#xff09;&#xff0c;解决的是什么&#xff1f; 图片和视频是非结构化数据&#xff0c;机器如果要理解某一图片或视频表达的内容&#xff0c;是无法直接分析的&#xff0c;这种情况&#xff0c;就需要有计算机视觉技术&#xff…...

python:画折线图

import pandas as pd import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties# 设置新宋体字体的路径 font_path D:/reportlab/simsun/simsun.ttf# 加载新宋体字体 prop FontProperties(fnamefont_path)""" # 读取 xlsx 文件 d…...

药品网站建设/百度推广新手入门

&#xff08;1&#xff09;黄金分割法&#xff08;0.618法&#xff09; 基本思想&#xff1a; 它通过对试探点的函数值进行比较&#xff0c;使得包含极小点的区间不断缩短&#xff0c;当区间长度小到精度范围之内时&#xff0c;可以粗略地认为区间上各点的函数值均接近于…...

做网站开发的女生多吗/seo排名快速上升

热身&#xff1a;轴承故障检测训练赛 任务 轴承有3种故障&#xff1a;外圈故障&#xff0c;内圈故障&#xff0c;滚珠故障&#xff0c;外加正常的工作状态。如表1所示&#xff0c;结合轴承的3种直径&#xff08;直径1,直径2,直径3&#xff09;&#xff0c;轴承的工作状态有10…...

手机网站优化指南/优秀营销软文范例300字

C# 中一切都是对象&#xff0c;对于文件操作&#xff0c;主要有两个静态类&#xff0c;分别是&#xff1a;File 和 Directory。 1. File 操作文件&#xff0c;静态类&#xff0c;对文件进行操作。拷贝、删除、剪切&#xff1b;2. Directory 操作目录&#xff08;文件夹&#…...

青县做网站/推广运营是什么工作

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 jmeter 性能测试数据…...

网站建设方案模板高校/东莞今日头条最新消息

09 Eclipse设置代码注释模版背景博客正文背景 在团队协作开发的项目中&#xff0c;为了降低沟通和维护成本&#xff0c;项目组成员使用统一的编码规范和注释规范显得尤为重要。本文就说一说如果在Eclipse中设置代码注释模版&#xff0c;技术经理可以要求所有的开发人员设置为统…...

做条形码哪个网站比较好/线上销售渠道有哪些

用过Windows XP系统的用户都知道&#xff0c;Windows XP有专用的窗口主题&#xff0c;很具特色。可是&#xff0c;Windows XP样式的窗口主题在默认的情况下&#xff0c;其标题栏都比较宽&#xff0c;尤其是显示器的分辨率为800600的时候&#xff0c;用IE浏览器或资源管理器时&a…...