AJAX这一篇就够啦~

news2024/12/23 10:03:00

AJAX这一篇就够啦~

  • AJAX
    • 1、AJAX概述
      • 1.1 AJAX简介
      • 1.2 XML简介
      • 1.3 AJAX的特点
    • 2、HTTP相关
      • 2.1 HTTP概述
      • 2.2 请求报文
      • 2.3 响应报文
      • 2.4 常见的响应状态码
      • 2.5 不同类型的请求及其作用
      • 2.6 一般http请求 与 ajax请求
    • 3、原生AJAX的使用
      • 3.1 准备工作
      • 3.2 核心对象
      • 3.3 GET请求
      • 3.4 POST请求
      • 3.5 json数据请求
      • 3.6 解决IE缓存问题
      • 3.7 请求超时和网络异常
      • 3.8 取消请求
      • 3.9 AJAX请求状态
      • 3.10 API总结
    • 4、jQuery-AJAX
      • 4.1 get请求
      • 4.2 post请求
      • 4.3 通用方法
    • 5、Axios-AJAX
    • 6、fetch-AJAX
    • 7、跨域
      • 7.1 同源策略
      • 7.2如何解决跨域

AJAX

1、AJAX概述

1.1 AJAX简介

  • AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML
  • 通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据
  • AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式

1.2 XML简介

  • XML可扩展标记语言
  • XML被设计用来传输和存储数据
  • XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据
<!--XML表示-->
<student>
	<name>孙情空</name>
	<age>18</age>
	<gender></gender>
</student>
//JSON表示
{"name":"孙悟空","age":18,"gender":"男"}

1.3 AJAX的特点

  • AJAX的优点
    1. 可以无需刷新页面而与服务器端进行通信
    2. 允许你根据用户事件来更新部分页面内容
  • AJAX的缺点
    1. 没有浏览历史,不能回退
    2. 存在跨域问题(同源)
    3. SEO不友好

2、HTTP相关

2.1 HTTP概述

  • HTTP(hypertext transport protocol)协议『超文本传输协议』,协议详细规定了浏览器和万维网服务器之间互相通信的规则

  • HTTP概述 - HTTP | MDN (mozilla.org)

  • HTTP交互:

    1. 前后应用从浏览器端向服务器发送HTTP 请求(请求报文)
    2. 后台服务器接收到请求后, 调度服务器应用处理请求, 向浏览器端返回HTTP响应(响应报文)
    3. 浏览器端接收到响应, 解析显示响应体/调用监视回调

2.2 请求报文

行      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=admin&password=admin

2.3 响应报文

行      HTTP/1.1  200  OK
头      Content-Type: text/html;charset=utf-8
        Content-length: 2048
        Content-encoding: gzip
空行    
体      <html>
            <head>
            </head>
            <body>
                <h1>尚硅谷</h1>
            </body>
        </html>

2.4 常见的响应状态码

  • 200 OK 请求成功。一般用于GET 与POST 请求
  • 201 Created 已创建。成功请求并创建了新的资源
  • 401 Unauthorized 未授权/请求要求用户的身份认证
  • 404 Not Found 服务器无法根据客户端的请求找到资源
  • 500 Internal Server Error 服务器内部错误,无法完成请求

2.5 不同类型的请求及其作用

  • GET: 从服务器端读取数据(查)
  • POST: 向服务器端添加新数据 (增)
  • PUT: 更新服务器端已有数据 (改)
  • DELETE: 删除服务器端数据 (删)

2.6 一般http请求 与 ajax请求

  • ajax请求是一种特别的 http请求
  • 对服务器端来说, 没有任何区别, 区别在浏览器端
  • 浏览器端发请求: 只有XHR 或fetch 发出的才是ajax 请求, 其它所有的都是非ajax 请求
  • 浏览器端接收到响应
    (1) 一般请求: 浏览器一般会直接显示响应体数据, 也就是我们常说的刷新/跳转页面
    (2) ajax请求: 浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据

3、原生AJAX的使用

3.1 准备工作

安装node.js

  • Node.js 中文网 (nodejs.cn)
  • 检查安装成功:node -v(命令行窗口)

安装express(服务端框架)

  • Express - 基于 Node.js 平台的 web 应用开发框架 - Express 中文文档 | Express 中文网 (expressjs.com.cn)

  • 操作步骤:

    1. 初始化环境:npm init --yes

    2. 下载express包:npm install express --save

    3. 编写js代码:

      // 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 端口监听中...");
       })
      
    4. 运行js程序:node .\01express使用.js

    5. 打开网页显示页面

    6. 调试程序可以查看请求和响应

安装nodemon自动重启工具

  • nodemon - npm (npmjs.com)
  • 步骤:
    1. 安装:npm install -g nodemon
    2. 启动服务:nodemon server.js

3.2 核心对象

  • 核心对象

    • XMLHttpRequest,AJAX的所有操作都是通过该对象进行的
  • 使用步骤

    1. 创建XMLHttpRequest对象

      var xhr = new XMLHttpRequest();
      
    2. 设置请求信息

      xhr.open(method, url);
      //可以设置请求头,一般不设置
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      
    3. 发送请求

      xhr.send(body)//get请求不传body参数,只有post 请求使用
      
    4. 接收响应

      //xhr.responseXML接收xml格式的响应数据
      //xhr.responseText接收文本格式的响应数据
      xhr.onreadystatechange = function (){
      		if(xhr.readyState == 4 &&xhr.status == 200){
      			var text = xhr.responseText;
      			console.log(text);
      	}
      }
      

3.3 GET请求

  • 点击返回响应信息

  • 创建浏览器端使用的html文件和服务端使用的js文件

在这里插入图片描述

  • 服务器端server.js
// 1. 引入express
const express = require('express');

// 2. 创建应用对象
const app = express();

// 3. 创建路由规则
app.get('/server', (request, response) => {
  // 设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  // 设置响应体
  response.send("Hello Ajax");
});

// 4. 监听服务
app.listen(8000, () => {
  console.log("服务已经启动, 8000 端口监听中...");
 })
  • 启动服务:node server.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 #90b;
        }
    </style>
</head>

<body>
    <button>点击发送请求</button>
    <div id="result"></div>

    <script>
        //获取button元素
        const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");
        //绑定事件
        btn.onclick = function () {
            //1. 创建对象
            const xhr = new XMLHttpRequest();
            //2. 初始化 设置请求方法和 url
            xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
            //3. 发送
            xhr.send();
            //4. 事件绑定 处理服务端返回的结果
            // on  when 当....时候
            // readystate 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
            // change  改变
            xhr.onreadystatechange = function () {
                //判断 (服务端返回了所有的结果)
                if (xhr.readyState === 4) {
                    //判断响应状态码 200  404  403 401 500
                    // 2xx 成功
                    if (xhr.status >= 200 && xhr.status < 300) {
                        //处理结果  行 头 空行 体
                        //响应 
                        // 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>

GET请求设置请求参数

  • 设置url参数:xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');

在这里插入图片描述

在这里插入图片描述

3.4 POST请求

  • 鼠标放到div中,发post请求,将响应体放在div中呈现

  • server.js添加post

//可以接收任意类型的请求 
app.all('/server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers', '*');
    //设置响应体
    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>AJAX POST 请求</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(){
            //1. 创建对象
            const xhr = new XMLHttpRequest();
            //2. 初始化 设置类型与 URL
            xhr.open('POST', 'http://127.0.0.1:8000/server');
            //设置请求头
            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');
            // xhr.send('1233211234567');
            
            //4. 事件绑定
            xhr.onreadystatechange = function(){
                //判断
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status < 300){
                        //处理服务端返回的结果
                        result.innerHTML = xhr.response;
                    }
                }
            }
        });
    </script>
</body>
</html>

在这里插入图片描述

设置请求头信息

// 设置请求体内容的类型
xhr.setRequesHeader('Content-Type','application/x-www-from-urlencoded');
// 自定义头信息
xhr.setRequesHeader('name', 'ashiyi');
  • server.js中设置响应头允许自定义请求头 post改成all
response.setHeader('Access-Control-Allow-Header','*');

3.5 json数据请求

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);
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON响应</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);
                        // result.innerHTML = data.name;
                        // 2. 自动转换
                        console.log(xhr.response);
                        result.innerHTML = xhr.response.name;
                    }
                }
            }
        }
    </script>
</body>
</html>

在这里插入图片描述

3.6 解决IE缓存问题

  • 问题:在一些浏览器中(IE),由于缓存机制的存在,ajax只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据
  • 解决方式:浏览器的缓存是根据url地址来记录的,所以我们只需要修改url地址即可避免缓存问题
  • xhr.open("get" ," /testAJAX?t="+Date.now());

3.7 请求超时和网络异常

  • 前端页面
// 超时设置 (2秒)
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){
	alert('网络超时,请稍后重试')
}
// 网络异常回调
xhr.onerror = function(){
	alert('网络异常,请稍后重试')
}
  • server.js
//延时响应
app.all('/delay', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    setTimeout(() => {
        //设置响应体
        response.send('延时响应');
    }, 1000)
});

3.8 取消请求

// 手动取消
xhr.abort()
<!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>
    <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>

3.9 AJAX请求状态

  • xhr.readyState 可以用来查看请求当前的状态
  • https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState
  • 0:表示XMLHttpRequest实例已经生成,但是open()方法还没有被调用
  • 1:表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定HTTP请求的头信息
  • 2:表示send()方法已经执行,并且头信息和状态码已经收到
  • 3:表示正在接收服务器传来的body 部分的数据
  • 4:表示服务器数据已经完全接收,或者本次接收已经失败了

3.10 API总结

  • XMLHttpRequest():创建 XHR 对象的构造函数
  • status:响应状态码值,如 200、404
  • statusText:响应状态文本,如 ’ok‘、‘not found’
  • readyState:标识请求状态的只读属性 0-1-2-3-4
  • onreadystatechange:绑定 readyState 改变的监听
  • responseType:指定响应数据类型,如果是 ‘json’,得到响应后自动解析响应
  • response:响应体数据,类型取决于 responseType 的指定
  • timeout:指定请求超时时间,默认为 0 代表没有限制
  • ontimeout:绑定超时的监听
  • onerror:绑定请求网络错误的监听
  • open():初始化一个请求,参数为:(method, url[, async])
  • send(data):发送请求
  • abort():中断请求 (发出到返回之间)
  • getResponseHeader(name):获取指定名称的响应头值
  • getAllResponseHeaders():获取所有响应头组成的字符串
  • setRequestHeader(name, value):设置请求头

4、jQuery-AJAX

4.1 get请求

  • $.get(url, [data], [callback], [type])
    • url:请求的URL地址
    • data:请求携带的参数
    • callback:载入成功时回调函数
    • type:设置返回内容格式,xml, html, script, json, text,_default

4.2 post请求

  • $.post(url, [data], [callback], [type])
    • url:请求的URL地址
    • data:请求携带的参数
    • callback:载入成功时回调函数
    • type:设置返回内容格式,xml, html, script, json, text,_default

4.3 通用方法

  • 前端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery 发送 AJAX 请求</title>
    <link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.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');
        });

        $('button').eq(1).click(function(){
            $.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
                console.log(data);
            });
        });

        $('button').eq(2).click(function(){
            $.ajax({
                //url
                url: 'http://127.0.0.1:8000/jquery-server',
                //参数
                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
                }
            });
        });
    </script>
</body>
</html>
  • server.js添加
//jQuery 服务
app.all('/jquery-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

5、Axios-AJAX

  • 前端界面
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>axios 发送 AJAX请求</title>
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
</head>

<body>
    <button>GET</button>
    <button>POST</button>
    <button>AJAX</button>

    <script>
        // https://github.com/axios/axios
        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 => {
                console.log(value);
            });
        }

        btns[1].onclick = function () {
            axios.post('/axios-server', {
                username: 'admin',
                password: 'admin'
            }, {
                //url 
                params: {
                    id: 200,
                    vip: 9
                },
                //请求头参数
                headers: {
                    height: 180,
                    weight: 180,
                }
            });
        }
    
        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.status);
                //响应状态字符串
                console.log(response.statusText);
                //响应头信息
                console.log(response.headers);
                //响应体
                console.log(response.data);
            })
        }
    </script> 
</body>

</html>
  • server.js添加
//axios 服务
app.all('/axios-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

6、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>
        //文档地址
        //https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
        
        const btn = document.querySelector('button');

        btn.onclick = function(){
            fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
                //请求方法
                method: 'POST',
                //请求头
                headers: {
                    name:'atguigu'
                },
                //请求体
                body: 'username=admin&password=admin'
            }).then(response => {
                // return response.text();
                return response.json();
            }).then(response=>{
                console.log(response);
            });
        }
    </script>
</body>
</html>
  • server.js添加
//fetch 服务
app.all('/fetch-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

7、跨域

7.1 同源策略

  • 同源策略(Same-Origin Policy)最早由Netscape公司提出,是浏览器的一种安全策略

  • 同源:协议、域名、端口号必须完全相同

  • 违背同源策略就是跨域

  • 前端页面

<!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>
  • server.js
const express = require('express');

const app = express();

app.get('/home', (request, response)=>{
    //响应一个页面
    response.sendFile(__dirname + '/index.html');
});

app.get('/data', (request, response)=>{
    response.send('用户数据');
});

app.listen(9000, ()=>{
    console.log("服务已经启动...");
});

7.2如何解决跨域

JSONP

  • JSONP是什么

    • JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求
  • JSONP工作流程

    • 在网页有一些标签天生具有跨域能力,比如:img link iframe script
    • JSONP就是利用script标签的跨域能力来发送请求的
  • JSONP的使用

    • 动态的创建一个script标签
    var script = document.createElement("script");
    
    • 设置script的 src,设置回调函数
    script.src = "http://localhost:3000/testAJAX?callback=abc";
    function abc(data){
               alert(data.name);
      };
    
    • 将script添加到body 中
    document.body.appendChild(script);
    
    • 服务器中路由的处理
    router.get("/testAJAX" , function (req , res) {
        console.log("收到请求");
    var callback = req.query.callback;
    var obj={
        name:"孙悟空",
        age:18
      }
      res.send(callback+"("+JSON.stringify(obj)+")");
    });
    
    • 原理

      • 前端页面
      <!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="http://127.0.0.1:5500/%E8%AF%BE%E5%A0%82/%E4%BB%A3%E7%A0%81/7-%E8%B7%A8%E5%9F%9F/2-JSONP/js/app.js"></script> -->
          <script src="http://127.0.0.1:8000/jsonp-server"></script>
      </body>
      
      </html>
      
      • server.js
      //jsonp服务
      app.all('/jsonp-server',(request, response) => {
          // response.send('console.log("hello jsonp")');
          const data = {
              name: '尚硅谷atguigu'
          };
          //将数据转化为字符串
          let str = JSON.stringify(data);
          //返回结果
          response.end(`handle(${str})`);
      });
      
    • JSONP实践

      • 前端页面
      <!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 标签的提示文本
                  p.innerHTML = data.msg;
              }
      
              //绑定事件
              input.onblur = function(){
                  //获取用户的输入值
                  let username = this.value;
                  //向服务器端发送请求 检测用户名是否存在
                  //1. 创建 script 标签
                  const script = document.createElement('script');
                  //2. 设置标签的 src 属性
                  script.src = 'http://127.0.0.1:8000/check-username';
                  //3. 将 script 插入到文档中
                  document.body.appendChild(script);
              }
          </script>
      </body>
      </html>
      
      • server.js中添加
      //用户名检测是否存在
      app.all('/check-username',(request, response) => {
          // response.send('console.log("hello jsonp")');
          const data = {
              exist: 1,
              msg: '用户名已经存在'
          };
          //将数据转化为字符串
          let str = JSON.stringify(data);
          //返回结果
          response.end(`handle(${str})`);
      });
      
    • JQuery中的JSONP

      • 前端页面
      <!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.bootcss.com/jquery/3.5.0/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){
                      $('#result').html(`
                          名称: ${data.name}<br>
                          校区: ${data.city}
                      `)
                  });
              });
          </script>
      </body>
      </html>
      
      • server.js中添加
      app.all('/jquery-jsonp-server',(request, response) => {
          // response.send('console.log("hello jsonp")');
          const data = {
              name:'尚硅谷',
              city: ['北京','上海','深圳']
          };
          //将数据转化为字符串
          let str = JSON.stringify(data);
          //接收 callback 参数
          let cb = request.query.callback;
      
          //返回结果
          response.end(`${cb}(${str})`);
      });
      

CORS

  • https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access control CORS

  • CORS

    • CORS(Cross-Origin Resource Sharing),跨域资源共享
    • CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和 post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
  • CORS工作过程

    • CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
  • 前端界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CORS</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>
  • server.js中添加
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-Origin", "http://127.0.0.1:5500");
    response.send('hello CORS');
});
<style>
    #result{
        width:200px;
        height:100px;
        border:solid 1px #90b;
    }
</style>
发送请求
~~~
  • server.js中添加
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-Origin", "http://127.0.0.1:5500");
    response.send('hello CORS');
});

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

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

相关文章

新岁序开,和Jina AI共同码梦! (奖品攻略大揭秘)

Jina AI 北京、深圳、柏林、湾区的小伙伴给您拜年啦&#xff01; Jina AI 开源社区致力于促进 多模态 AI 技术 的应用落地以及传播&#xff0c;一直以来&#xff0c;我们都为拥有这样一个全球化、多元化和高速发展的社区而感到自豪和感激&#xff01;正值新年之际&#xff0c;我…

从C和C++内存管理来谈谈JVM的垃圾回收算法设计-下

从C和C内存管理来谈谈JVM的垃圾回收算法设计-下引言基本概念对象GC ROOTS垃圾回收常见算法标记清除优缺点引用计数优缺点部分标记清除算法优缺点复制算法优缺点多空间复制算法标记整理(标记压缩)优缺点分代设计HotSpot具体实现跨代引用并发可行性经典垃圾回收器Serial新生代垃圾…

Binding常用辅助属性、多重绑定、优先级绑定

Binding常用辅助属性、多重绑定、优先级绑定 Binding常用辅助属性 StringFormat <Window.Resources><sys:Int32 x:Key"myInt">200</sys:Int32><sys:Single x:Key"mySingle">100.123456</sys:Single> </Window.Resourc…

Linux 中断控制器(五):中断号映射

中断号分为硬件中断号(HW ID)和软件中断号(IRQ number)。 这里有两个中断控制器,处理完毕进入 CPU。外设和中断控制器连接在一起,外设给中断控制器的是硬件中断号,如果中断控制器有级联,那么硬件中断号在不同的中断控制器中可能会重复。但是到了 CPU 以后,我们需要对不…

C语言:分支语句和循环语句

往期文章 C语言&#xff1a;初识C语言 目录往期文章前言1. 什么是语句2. 分支语句&#xff08;选择结构&#xff09;2.1 if语句2.2 switch语句3. 循环语句3.1 while循环3.2 for循环3.3 do while 循环3.4 goto语句后记前言 趁热打铁啊。写完该系列第一篇博客我就来劲了&#x…

TicTacToe: 基于时序差分TD(0)算法的agent实现以及完整python实现框架

目录 1. 前言 2. TD(0) 3. 实现要点解读 3.1 Class Env 3.2 Class State 3.3 Class Agent 3.3.1 class TD0Agent(Agent) 3.3.2 class MinimaxAgent 3.3.3 class RandomAgent(Agent) 3.3.4 class HumanPlayer(Agent) 3.4 棋盘和玩家的表示 4. Utility Function 4.1…

Redis02之使用java代码操作Redis

目录 1、可视化管理工具redis-desktop-manager安装与配置 ​编辑 2、Java访问redis 注1&#xff1a;不需要记得API的方法&#xff0c;只需要查redis命令 3、web3.0设置 1、可视化管理工具redis-desktop-manager安装与配置 1.1 双击redis-desktop-manager-0.8.8.384.exe即可…

【LeetCode】2293. 极大极小游戏

2293. 极大极小游戏 题目描述 给你一个下标从 0 开始的整数数组 nums &#xff0c;其长度是 2 的幂。 对 nums 执行下述算法&#xff1a; 设 n 等于 nums 的长度&#xff0c;如果 n 1 &#xff0c;终止 算法过程。否则&#xff0c;创建 一个新的整数数组 newNums &#xf…

自动驾驶轨迹生成-贝塞尔(Bézier)曲线

引言 最近刚看完贝塞尔曲线&#xff0c;工作就遇到了相应的需求&#xff0c;所以写一下过程。主要讲的是自动驾驶中&#xff0c;车换道时用到贝塞尔曲线&#xff0c;当然其他的很多领域也会有&#xff0c;例如图形学等。 在车遇到障碍物或者是前车速度较慢的时候&#xff0c;…

【编译原理核心知识点总结】第三章、正则文法、NFA、DFA

阅读规范&#xff1a; 本文以重点为主&#xff0c;零碎知识点/相对不够重要的为辅助阅读内容&#xff0c;以脚注形式给出&#xff0c;点击脚注即可快速跳转。助解题目通常是为了帮助理解给出的题目&#xff0c;考试不考&#xff0c;若已理解可直接跳过。文中提到的课本是陈火旺…

SpringBoot 并发编程学习历程(绝对的干货)

如果一个项目总用单线程来跑&#xff0c;难免会遇到一些性能问题&#xff0c;所以再开发中&#xff0c;我们应该尽量适量的使用多线程&#xff08;在保证线程安全的情况下&#xff09;。 本教程大概目录&#xff1a; 1.模拟单线程情节 2.用Callable实现 并发编程 3.用DeferedR…

高并发系统设计 --基于bitmap的用户签到

业务需求分析 一般像微博&#xff0c;各种社交软件&#xff0c;游戏等APP&#xff0c;都会有一个签到功能&#xff0c;连续签到多少天&#xff0c;送什么东西&#xff0c;比如&#xff1a; 签到1天送10积分&#xff0c;连续签到2天送20积分&#xff0c;3天送30积分&#xff0…

Qt之QDrag的使用(含源码+注释)

一、效果示例图 提示&#xff1a;主控件&#xff08;CDragTest界面&#xff0c;UI中中包含CWidget界面&#xff09;&#xff1b;子控件&#xff08;CWidget界面&#xff0c;在CDragTest界面添加&#xff09; 提示&#xff1a;源码中拖拽数据设置的文本不同&#xff0c;是博主准…

【ONE·C || 分支循环】

总言 C语言&#xff1a;分支循环。 文章目录总言1、分支语句1.1、if语句1.1.1、基本格式1.1.2、逻辑真假与悬空else1.1.3、练习1.2、switch语句1.2.1、基本格式&#xff1a;break、case、default1.2.2、练习&#xff1a;switch语句嵌套2、循环语句2.1、while循环2.1.1、基本格式…

uniapp实现界面可任意拖动小图标

uniapp实现界面可任意拖动小图标一、问题&#xff1a;二、解决步骤2.1 根据uni-app官方提供的案例&#xff0c;创建组件2.2 在需要的界面引入组件使用额外注意一、问题&#xff1a; 例如购物车小图标可任意拖动 二、解决步骤 2.1 根据uni-app官方提供的案例&#xff0c;创建…

Kubernetes教程(二)---集群网络之 Flannel 核心原理

来自&#xff1a;指月 https://www.lixueduan.com 原文&#xff1a;https://www.lixueduan.com/posts/kubernetes/02-cluster-network/ 本文主要记录了 Kubernetes 集群网络方案之 Flannel 核心原理详解&#xff0c;包括其隧道方案中的两种&#xff1a;UDP 实现和 VXLAN 实现…

Mysql之增删改查

这里的增删改查主要是对应表中的数据&#xff0c;不像前一篇那个列类型&#xff0c;耳机具体的哪一条数据 Insert 其实我们前面都用过好多次了 比如下面那个 可以 关于那个表名后面加不加&#xff08;列类型&#xff09;&#xff0c;下面有解释 INSERT INTO shanpin VALUES…

关于yolov8一些训练的情况

U神出品了最新的yolov8&#xff0c;从公开的参数量来看确实很优秀&#xff01;&#xff01;&#xff01;&#xff01;比如下图得一些指标&#xff1a; 可以看到s模型640得map已经达到了44.9&#xff0c;v8n得map也已经达到了37.3&#xff0c;很强了&#xff0c;但是实际上是怎么…

Python爬虫之Scrapy框架系列(3)——项目实战【某瓣top250电影信息获取】

目录&#xff1a;1. 某瓣电影top250首页电影信息的获取&#xff01;1.创建项目&#xff1a;2.创建爬虫文件&#xff1a;3.运行爬虫文件&#xff1a;4.设置请求头&#xff1a;5.获取到电影名字&#xff1a;5.1 使用shell交互式平台&#xff1a;5.1.1 首先&#xff1a;打开我们的…

239页10万字“联、管、用”三位一体雪亮工程整体建设方案

【版权声明】本资料来源网络&#xff0c;知识分享&#xff0c;仅供个人学习&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间删除&#xff01;完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 目录 1、 项目概述 1.1 项目背…