当前位置: 首页 > 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;查看和管理你的下载文件…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...