• AJAX 入门笔记


    课程地址

    AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
    AJAX 不是新的编程语言,而是一种使用现有标准的新方法
    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容
    XMLHttpRequest 只是实现 Ajax 的一种方式。

    XML

    可扩展标记语言,用来存储和传输数据(序列化),其于 HTML 类似,但是 XML 中的标签不是预定义的,而是自定义的

    var s1 = {
    	name: "daniel",
    	age: 18,
    	gender: "M"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    用 XML 表示为:

    <student>
    	<name>danielname>
    	<age>18age>
    	<gender>Mgender>
    student>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    现在基本被 json 代替:

    {
    	"name": "daniel",
    	"age": "18",
    	"gender": "M"
    }	
    
    • 1
    • 2
    • 3
    • 4
    • 5

    AJAX 的优缺点

    优点

    • 可以不刷新页面与服务器进行通信
    • 允许根据用户事件更新部分页面内容

    缺点

    • 没有浏览历史,不能回退
    • 存在跨域问题
    • SEO 不友好

    HTTP 报文格式

    post 请求:
    在这里插入图片描述
    响应:
    在这里插入图片描述

    express

    npm init --yes	# 初始化工程
    npm install express		# 安装 express
    
    • 1
    • 2

    AJAX 发送 GET 请求

    服务端代码如下:

    const express = require('express');
    const app = express();
    
    app.get('/server', (request, response) => {
        // 允许跨域
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.send('hello, world');
    });
    
    app.listen(8000, () => {
        console.log("listening on 8000");
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    前端代码如下:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <style>
            #result{
                width: 200px;
                height: 100px;
                border: solid 2px red;
            }
        style>
    head>
    <body>
        <button>发送请求button>
        <div id="result">div>
    body>
    <script>
        const btn0 = document.getElementsByTagName('button')[0];
        btn0.onclick = function() {
            // 1. 创建对象
            const xhr = new XMLHttpRequest();
            const result = document.getElementById('result')
            // 2. 初始化
            xhr.open('GET', 'http://127.0.0.1:8000/server');
            // 3. 发送
            xhr.send();
            /* 
                4. 事件绑定,处理服务端返回的结果。state 有如下 5 个值:
                0:未初始化
                1:open 方法调用完毕
                2:send 方法调用完毕
                3:服务端返回了部分结果
                4:服务端返回了全部结果
            */
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) { // 服务端返回了所有结果
                    if (xhr.status >= 200 && xhr.status < 300) {
                       result.innerHTML = xhr.response;
                    }
                }
            }
        }
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    GET 设置请求参数

    查询字符串参数以 ? 开始,以 & 分隔:

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

    AJAX 发送 POST 请求

    服务端添加处理 post 请求的回调函数:

    app.post('/server', (request, response) => {
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.send('hello, post');
    });
    
    • 1
    • 2
    • 3
    • 4

    前端:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: solid 2px red;
        }
    style>
    <body>
        <div id="result">div>
    body>
    <script>
        const result = document.getElementById('result');
        result.addEventListener('mouseover', function() {
            // console.log('mouseover');
            const xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://localhost:8000/server');
            xhr.send();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        result.innerHTML = xhr.response;
                    }
                }
            };
        });
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    POST 设置请求体

    xhr.send('a=100&b=200&c=300');
    xhr.send('a:100&b:200&c:300');
    
    • 1
    • 2

    设置请求头信息

    一般将身份参数信息放入请求头

    xhr.setRequestHeader('Content-Type', 'application/x-www-from-urlencoded');
    xhr.setRequestHeader('name', 'application/x-www-from-urlencoded');
    
    • 1
    • 2

    服务端代码加入:

    app.all('/server', (request, response) => {
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.setHeader('Access-Control-Allow-Headers', '*');	// 允许所有请求头
        response.send('hello, post');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    服务端响应 JSON 数据

    服务端返回一个 json 字符串

    app.all('/json-server', (request, response) => {
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.setHeader('Access-Control-Allow-Headers', '*');
        const data = {
            name: 'daniel'
        };
        response.send(JSON.stringify(data));	// 序列化
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    客户端从 json 字符串中解析出 json 对象:

    <script>
        const result = document.getElementById('result');
        window.onkeydown = function() {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', 'http://localhost:8000/json-server');
            xhr.send();
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        //result.innerHTML = xhr.response;
                        let data = JSON.parse(xhr.response);	// 反序列化
                        result.innerHTML = data.name;
                    }
                }
            }
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    安装 nodemon,在修改服务端代码后能够自动重启 nodejs

    npm install -g nodemon
    
    • 1

    使用 nodemon 启动 nodejs:

    nodemon server.js
    
    • 1

    ie 缓存问题:ie 会缓存 ajax 的请求结果,如果服务端修改了响应内容,ie 不能及时地呈现。解决方法:在请求后面加上时间戳参数,使得每次请求内容都不同

    请求超时与网络异常

    对 ajax 做超时设置,给用户提醒

    服务端设置延时发送响应:

    app.all('/timeout', (request, response) => {
        response.setHeader('Access-Control-Allow-Origin', '*');
        setTimeout(() => {  // 延时发送
            response.send('hello, timeout 3s');
        }, 3000);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    前端代码添加超时和网络异常处理:

    <script>
        const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById('result');
        btn.addEventListener('click', function() {
            // console.log('mouseover');
            const xhr = new XMLHttpRequest();
            xhr.timeout = 2000;		// 给 ajax 设置超时
            xhr.ontimeout = () => { // 超时回调
                alert("timeout!!!");
            }
            xhr.onerror = () => {   // 网络异常回调
                alert("bad network!!!");
            }
            xhr.open('POST', 'http://localhost:8000/timeout');
            xhr.send();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        result.innerHTML = xhr.response;
                    }
                }
            };
        });
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    取消请求

    使用 abort() 方法即可:

    <body>
        <button>点击发送请求</button>
        <button>点击取消请求</button>
    </body>
    <script>
        const btn1 = document.getElementsByTagName('button')[0];
        const btn2 = document.getElementsByTagName('button')[1];
        let xhr = null;
        btn1.onclick = function() {
            xhr = new XMLHttpRequest();
            xhr.open('GET', 'http://localhost:8000/timeout');
            xhr.send();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        console.log(xhr.response);
                    }
                }
            };
        };
        btn2.onclick = function () {
            xhr.abort();
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    重复发送请求问题

    设置标志变量,判断是否重复发送:

    <script>
        const btn0 = document.getElementsByTagName('button')[0];
        const btn1 = document.getElementsByTagName('button')[1];
        let xhr = null;
        let isSending = false;
        btn0.onclick = function() {
            if (isSending) {
                xhr.abort();
            }
            xhr = new XMLHttpRequest();
            isSending = true;
            xhr.open('GET', 'http://localhost:8000/timeout');
            xhr.send();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    isSending = false;  // 请求发送完成
                    if (xhr.status >= 200 && xhr.status < 300) {
                        console.log(xhr.response);
                    }
                }
            };
        };
        btn1.onclick = function () {
            xhr.abort();
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    jQuery 发送 AJAX 请求

    get/post 方法

    服务端:

    app.all('/jquery-server', (request, response) => {
        response.setHeader('Access-Control-Allow-Origin', '*');
        const data = {name: "daniel"}
        response.send(JSON.stringify(data));
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    前端:

    <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>
    </body>
    <script>
        $('button').eq(0).click(function() {
            $.get('http://localhost:8000/jquery-server', {a: 100, b: 200}, function(data) {
                console.log(data);
            }, 'json');     // 响应体是一个 json 格式数据,而非普通字符串
        });
        $('button').eq(1).click(function() {
            $.post('http://localhost:8000/jquery-server', {a: 100, b: 200}, function(data) {
                console.log(data);
            });
        });
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    通用方法

    通用方法可以设置任意 http 请求字段

    <script>
        $('button').eq(2).click(function() {
            $.ajax({
                url: 'http://localhost:8000/timeout',
                data: {a: 100, b: 200},
                type: 'GET',
                dataType: 'json',       // 响应体结果
                success: function(data) {
                    console.log(data);
                },
                timeout: 2000,
                error: function(data) {
                    console.log("error!!!")
                },
                headers: {
                    a: 300,
                    b: 400
                }
            });
        });
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    axios 发送 AJAX 请求

    服务端:

    const express = require('express');
    const app = express();
    
    app.all('/server', (request, response) => {
        // 允许跨域
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.setHeader('Access-Control-Allow-Headers', '*');
        response.send('hello, world');
    });
    
    app.listen(8000, () => {
        console.log("listening on 8000");
    })
    
    app.all('/axios-server', (request, response) => {
        // 允许跨域
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.setHeader('Access-Control-Allow-Headers', '*');
        const data = {name: 'daniel'};
        response.send(JSON.stringify(data));
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    前端:

    <body>
        <button>GETbutton>
        <button>POSTbutton>
        <button>AJAXbutton>
    body>
    <script>
        const btns = document.querySelectorAll('button');
        axios.defaults.baseURL = 'http://localhost:8000';
        btns[0].onclick = function() {
            axios.get('/axios-server', {
                params: {
                    id: 100,
                    vip: 7
                },
                headers: {
                    name: 'daniel',
                    age: 18
                }
            }).then(value => {
                console.log(value);
            });
        }
        btns[1].onclick = function() {
            axios.post('axios-server', {
                    username: 'admin',
                    password: '123456'
                }, {
                params: {
                    id: 200,
                    vip: 8
                },
                headers: {
                    height: 180,
                    weight: 80
                }
            });
        }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    axios 函数发送 ajax 请求

    函数语法:

    // Send a POST request
    axios({
      method: 'post',
      url: '/user/12345',
      data: {
        firstName: 'Fred',
        lastName: 'Flintstone'
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    前端代码:

        btns[2].onclick = function() {
            axios({
                method: 'POST',
                url: '/axios-server',
                params: {
                    vip: 10,
                    level: 30
                },
                headers: {
                    a: 100,
                    b: 200
                },
                data: {
                    username: 'admin',
                    password: '123456'
                }
            }).then(response => {
                console.log(response.status);
                console.log(response.statusText);
                console.log(response.headers);
                console.log(response.data);
            });
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    fetch 函数发送 AJAX 请求

    服务端:

    app.all('/fetch-server', (request, response) => {
        // 允许跨域
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.setHeader('Access-Control-Allow-Headers', '*');
        const data = {name: 'daniel'};
        response.send(JSON.stringify(data));
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    前端:

    <body>
        <button>ajaxbutton>
    body>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function() {
            fetch('http://localhost:8000/fetch-server', {
                method: 'POST',
                headers: {
                    name: 'daniel'
                },
                body: 'username=admin&password=admin'
            }).then(response => {
                // return response.text();
                return response.json();
            }).then(response => {
                console.log(response);
            });
        }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    同源策略

    同源策略是一种安全策略,所谓“同源”就是指协议,域名,端口号完全相同。违背同源策略的行为就是跨域

    AJAX 默认是需要遵守同源策略的

    多台服务器就存在跨域问题

    服务端:

    const express = require('express');
    const app = express();
    
    app.all('/home', (request, response) => {
        response.sendFile(__dirname + '/home.html');
    });
    
    app.all('/data', (request, response) => {
        response.send('userdata');
    });
    
    app.listen(9000, () => {
        console.log("listening 9000");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    前端:

    <body>
        <h1>daniel</h1>
        <button onclick="">get userdata</button>
    </body>
    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    JSONP

    JSONP 原理

    JSON with padding

    JSONP 是一个非官方的跨域解决方案,只支持 get 请求

    JSONP 利用网页中有一些标签天生具有跨域能力,比如 img link iframe script 等

    在前端声明 handle 函数,在 script 中引用:

    const data = {
        name: 'daniel'
    };
    
    handle(data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>jsonptitle>
        <style>
            #result{
                width: 300px;
                height: 100px;
                border: solid 5px #78a;
            }
        style>
    head>
    <body>
        <div id="result">div>
        <script>
            function handle(data) {
                const result = document.getElementById('result');
                result.innerHTML = data.name;
            }
        script>
    body>
    <script src="jsonp.js">script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    script 中请求到的 js 代码会立即被解释执行

    使用 script 标签完成跨域请求:

    <script src="http://localhost:8000/jsonp-server"></script>
    
    • 1

    服务端对应如下规则:

    app.all('/jsonp-server', (request, response) => {
        response.send('hello, jsonp-server');
    });
    
    • 1
    • 2
    • 3

    响应能够正常返回,但是 console 爆 jsonp-server:1 Uncaught ReferenceError: hello is not defined 错误,原因在于相应内容被当作 js 代码解释执行了

    app.all('/jsonp-server', (request, response) => {
        response.send('console.log("hello, jsonp-server")');
    });
    
    • 1
    • 2
    • 3

    jsonp:返回一个函数调用语句,其实参就是需要返回的数据,函数的定义在前端,函数的实参在后端传入。服务端代码如下:

    app.all('/jsonp-server', (request, response) => {
        const data = {
            name: 'daniel'
        };
        let data_str = JSON.stringify(data);
        response.end(`handle(${data_str})`);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    JSONP 实践

    步骤:

    • 创建 script 标签
    • 设置 src 为跨域目标地址,向服务端请求“js代码”
    • 将 script 添加到 body

    前端定义 handle 函数,后端返回一个函数调用的 js 代码,其中的实参由对象的字面量得到

    服务端代码:

    app.all('/check-username', (request, response) => {
        const data = {
            exist: 1,
            msg: 'username exists'
        };
        let data_str = JSON.stringify(data);
        response.end(`handle(${data_str})`);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    前端代码:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>usertitle>
    head>
    <body>
        用户名:<input type="text" id="username">
        <p>p>
    body>
    <script>
        const input = document.querySelector('input');
        const p = document.querySelector('p');
        function handle(data) {
            input.style.border= 'solid 2px #f00'
            p.innerHTML = data.msg;
        }
    
        input.onblur = function() {
            let uname = this.value;
            const script = document.createElement('script');
            script.src = 'http://localhost:8000/check-username';
            document.body.appendChild(script);
        }
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    jquery 发送 JSONP 请求

    前端:

    <body>
        <button>jsonp requestbutton>
        <div id="result">div>
    body>
    <script>
        $('button').eq(0).click(function(){
            $.getJSON('http://localhost:8000/jquery-jsonp-server?callback=?', function(data) {
                $('#result').html(`
                    姓名:${data.name},
                    校区:${data.city}
                `);
            });
        });
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    服务端:

    app.all('/jquery-jsonp-server', (request, response) => {
        const data = {
            name: 'daniel',
            city: ['bj', 'sh', 'sz']
        };
        let data_str = JSON.stringify(data);
        let cb = request.query.callback;
        response.end(`${cb}(${data_str})`);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    CORS

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

    服务端:

    app.all('/cors-server', (request, response) => {
        // 允许跨域
        response.setHeader('Access-Control-Allow-Origin', '*');
        response.send('hello, cors');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    前端:

    <body>
        <button>cors requestbutton>
        <div id="result">div>
    body>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function() {
            const x = new XMLHttpRequest();
            x.open('GET', 'http://localhost:8000/cors-server');
            x.send();
            x.onreadystatechange = function() {
                if (x.readyState === 4) {
                    if (x.status >= 200 && x.status < 300) {
                        console.log(x.response);
                    }
                }
            };
        }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    10 个最佳免费 PDF 压缩工具软件
    Vue3模块找不到问题解决:找不到模块‘vue ‘。你的意思是将“模块解决方案”选项设置为“节点”,还是添加ali
    AI机器人跑 [地铁跑酷]
    Golang小数点保留
    贴片天线的特征模分析及其应用
    【LeetCode刷题(数据结构)】:另一颗树的子树
    计算机图形学 实验二:曲线拟合
    哪个视觉语言模型更优?InstructBLIP、MiniGPT-4?全面评估基准LVLM-eHub告诉你
    Qt应用开发(基础篇)——普通按钮类 QPushButton QCommandLinkButton
    良品铺子、三只松鼠、来伊份双11内卷!谁是“新王”?
  • 原文地址:https://blog.csdn.net/DanielSYC/article/details/133233045