AJAX知识点(前后端交互技术)

news2024/12/27 13:32:47

原生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.com
      Cookie:name=guigu
      Content-type:application/x-www-form-urlencoded
      User-Agent:chrome 83    
  空行
  体  username=admain&password=admin如果是GET请求,请求体是空的,如果是POST请求,请求体可以不为空

响应报文

  行  HTTP/1.1(协议版本)   200(协议状态码)  ok(协议字符串)
  头  Content-Type:text/html;charset=utf-8
      Content-length:2048
      Content-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.初始化 设置请求方法和URL
      xhr.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.初始化 设置类型与URL
      xhr.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.初始化 设置类型与URL
      xhr.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=null
    btns[0].onclick=function(){
      x=new XMLHttpRequest()
      x.open('GET','http://127.0.0.1:8000/delay')
      x.send()
    }
    // abort
    btns[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=true
      x.open('GET','http://127.0.0.1:8000/delay')
      x.send()
      x.onreadystatechange=function(){
        if(x.readyState===4){
          // 修改标识变量
          isSending=false
        }
      }
    }
    // abort
    btns[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({
        //url
        url:'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')
    // 配置baseURL
    axios.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'
        },{
        // url
        params:{
          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',
        // url
        url:'/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')
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1657306.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中小学校活动向媒体投稿报道宣传有哪些好方法

作为一所中小学校的教师,我肩负着向外界展示学校风采、宣传校园文化活动的重要使命。起初,每当学校举办特色活动或取得教学成果时,我都会满怀热情地撰写新闻稿,希望通过媒体的平台让更多人了解我们的故事。然而,理想丰满,现实骨感,我很快发现,通过电子邮件向媒体投稿的过程充满…

ICode国际青少年编程竞赛- Python-1级训练场-变量的计算

ICode国际青少年编程竞赛- Python-1级训练场-变量的计算 1、 a 2 for i in range(4):Spaceship.step(a-1)Dev.step(a)Dev.step(-a)a a 12、 a 2 for i in range(4):Dev.step(2 a)Dev.step(-a)Dev.turnRight()a a 13、 y 4 for i in range(3):Dev.step(y)Dev.turnRigh…

计算方法实验9:Romberg积分求解速度、位移

任务 输出质点的轨迹 ( x ( t ) , y ( t ) ) , t ∈ { 0.1 , 0.2 , 0.3 , . . . , 10 } (x(t), y(t)), t\in \{0.1, 0.2, 0.3, ..., 10\} (x(t),y(t)),t∈{0.1,0.2,0.3,...,10}&#xff0c;并在二维平面中画出该轨迹.请比较M分别取4, 8, 12, 16, 20 时&#xff0c;Romberg积分达…

去除视频背景音乐或人物声音的4种方法,建议收藏

你是否曾想移除视频中令人分心的声音呢&#xff1f;对于需要裁剪声音或去除背景噪音的视频来说&#xff0c;消音是一种非常有用的技能。那么&#xff0c;视频怎么消除声音&#xff1f;看看下文就知道了。 方法一&#xff1a;使用 智优影 去除视频中的音频 在线转换工具不仅支持…

Python轻量级Web框架Flask(13)—— Flask个人博客项目

0、前言: ★这部分内容是基于之前Flask学习内容的一个实战项目梳理内容,没有可以直接抄下来跑的代码,是学习了之前Flask基础知识之后,再来看这部分内容,就会对Flask项目开发流程有更清楚的认知,对一些开发细节可以进一步的学习。项目功能,通过Flask制作个人博客。项目架…

又一个限时免费生成图片的AI平台

网址 https://jimeng.jianying.com/ai-tool/image/generate 抖音官方的文升图&#xff0c;用抖音登录就可以&#xff0c;每天送60积分&#xff0c;目前看文生图好像是限时免费。 随手试了一下&#xff0c;速度很快&#xff0c;质量也还可以&#xff0c;背靠大厂&#xff0c;…

福建 | 福建铭发用行动诠释“敢为天下先”的泉州精神

福建铭发 泉州TOP级企业 在福建&#xff0c;提到混凝土搅拌站&#xff0c;铭发是绕不开的一个存在。 他们是当地最早一批建成的商砼企业&#xff0c;也是如今发展规模最大的TOP级企业。 从2007年建站至今&#xff0c;近15年的发展&#xff0c;他们形成了一套铭发特色的企业经…

【qt】容器的用法

容器目录 一.QVertor1.应用场景2.增加数据3.删除数据4.修改数据5.查询数据6.是否包含7.数据个数8.交换数据9.移动数据10.嵌套使用 二.QList1.应用场景2.QStringList 三.QLinkedList1.应用场景2.特殊点3.用迭代器来变量 四.QStack1.应用场景2.基本用法 五.QQueue1.应用场景2.基本…

WPF之改变任务栏图标及预览

1&#xff0c;略缩图添加略缩按钮。 <Window.TaskbarItemInfo><TaskbarItemInfo x:Name"taskInfo" ProgressState"None" ProgressValue"0.6" ><TaskbarItemInfo.ThumbButtonInfos><ThumbButtonInfo x:Name"btiPlay&q…

分享10个高质量宝藏网站~

分享一波高质量宝藏网站~ 这10个宝藏网站&#xff0c;个个都好用到爆&#xff0c;娱乐、办公、学习都能在这里找到&#xff01; 1、Z-Library https://zh.zlibrary-be.se/ 世界最大的免费电子书下载网站&#xff01;电子书资源超千万&#xff0c;不过这个网站不太稳定&#…

[Kubernetes] KubeKey 部署 K8s v1.28.8

文章目录 1.K8s 部署方式2.操作系统基础配置3.安装部署 K8s4.验证 K8s 集群5.部署测试资源 1.K8s 部署方式 kubeadm: kubekey, sealos, kubespray二进制: kubeaszrancher 2.操作系统基础配置 主机名内网IP外网IPmaster192.168.66.2139.198.9.7node1192.168.66.3139.198.40.17…

Java_File

介绍&#xff1a; File对象表示路径&#xff0c;可以是文件&#xff0c;也可以是文件夹。这个路径可以是存在的&#xff0c;也可以是不存在的&#xff0c;带盘符的路径是绝对路径&#xff0c;不带盘符的路径是相对路径&#xff0c;相对路径默认到当前项目下去找 构造方法&…

MGRE 实验

需求&#xff1a;1、R2为ISP&#xff0c;其上只能配置IP地址。 2、R1-R2之间为HDLC封装 3、R2-R3之间为ppp封装&#xff0c;pap认证&#xff0c;R2为主认证方。 4、R2-R4之间为ppp封装&#xff0c;chap认证&#xff0c;R2为主认证方。 5、R1、R2、R3构建MGRE环境&#xff0…

汽车之家,如何在“以旧换新”浪潮中大展拳脚?

北京车展刚刚落幕&#xff0c;两重利好正主导汽车市场持续升温&#xff1a;新能源渗透率首破50%&#xff0c;以及以旧换新详细政策进入落地期。 图源&#xff1a;中国政府网 在政策的有力指引下&#xff0c;汽车产业链的各个环节正经历着一场深刻的“连锁反应”。在以旧换新的…

STM32——GPIO输出(点亮第一个LED灯)

代码示例&#xff1a; #include "stm32f10x.h" // Device headerint main() {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitSt…

【JAVA基础之Stream流】掌握Stream流

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1.Stream流 1.1 概述 2.2 常见方法 2.2.1 实现步骤 2.2.2 获取Stream的方式 2.2.3 中间方法 2.2.4 终结方法 1.Stream流 1.1 概述 Stream流可以让你通过链…

Spring AOP(2)

目录 Spring AOP详解 PointCut 切面优先级Order 切点表达式 execution表达式 切点表达式示例 annotation 自定义注解MyAspect 切面类 添加自定义注解 Spring AOP详解 PointCut 上面代码存在一个问题, 就是对于excution(* com.example.demo.controller.*.*(..))的大量重…

Cmake编译源代码生成库文件以及使用

在项目实战中&#xff0c;通过模块化设计能够使整个工程更加简洁明了。简单的示例如下&#xff1a; 1、项目结构 project_folder/├── CMakeLists.txt├── src/│ ├── my_library.cpp│ └── my_library.h└── app/└── main.cpp2、CMakeList文件 # CMake …

[机器学习系列]深入探索回归决策树:从参数选择到模型可视化

目录 一、回归决策树的参数 二、准备数据 三、构建回归决策树 (一)拟合模型 (二)预测数据 (三)查看特征重要性 (四)查看模型拟合效果 (五) 可视化回归决策树真实值和预测值 (六)可视化决策树并保存 部分结果如下&#xff1a; 一、回归决策树的参数 DecisionTreeRegress…

基于springboot+mybatis+vue的项目实战之增删改查CRUD

目录结构 PeotController.java package com.example.controller;import com.example.pojo.Peot; import com.example.pojo.Result; import com.example.service.PeotService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web…