【ajax】

原生得AJAX

ajax的简介

AJAX 全称为Asynchronous JavaScript And XML ,就是异步的js 和XML

通过ajax 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据

AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

XML 简介

XML可以扩展标记语言

XML 被设计用来传输和存储数据

XML 和 HTML相似,不同的事HTM种中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据

比如说我有应该学生数据:
name = '孙悟空';age = 18;gender = "男";
用XML表示
<student>
	<name>孙悟空</name>
	<age>18</age>
    <gender>男</gender>
</student>

现在已经被json取代了

用json表示:

{"name":"孙悟空","age":18,"gender":"男"}

AJAX的特点

优点

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

缺点

  1. 没有浏览历史,不能退回
  2. 存在跨域问题(同源)
  3. SEO不友好

AJAX的使用

核心对象

AJAX 设置请求参数

GET请求

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <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>
        // 获取btutton元素
        const btn = document.getElementsByTagName("button")[0];
        const result = document.getElementById("result");
        // 绑定事件
        btn.onclick = function() {
            //1、创建对象
            const xhr = new XMLHttpRequest();

            // 2、设置请求的方法
            xhr.open("GET", "http://127.0.0.1:8000/server?a=100&b=200&c=300"); //a=100 b=200 c=300 为参数

            // 3、发送
            xhr.send();

            // 4、事件绑定  服务端的返回的结果
            // on 当  点击得时候
            // readystate 是xhr 对象中的属性,表示状态 0 1 2 3 4
            // change 改变
            xhr.onreadystatechange = function() {
                // 判断 (服务端都会所有的结果)
                if (xhr.readyState === 4) {
                    // 判断响应码 200 404 403 401 500  以2开头的都表示成功
                    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>

server.js

// 1、引入express
const { response } = require("express");
const express = require("express");

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

// 3、创建路由规则
/**
 *  request 是对请求报文的封装
 *  respon  是对响应报文的封装
 */
app.get("/server", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");

    // 设置响应
    response.send("HELLO EXPRESS");
});

// all 可以接受任意请求
app.all("/server", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");

    // 响应头  '*'表示所有的头信息 都可以接受
    response.setHeader("Access-Control-Allow-Headers", "*");
    // 设置响应
    response.send("HELLO EXPRESS POST");
});
// 延时响应
app.all("/delay", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");
    response.setHeader("Access-Control-Allow-Headers", "*");
    setTimeout(() => {
        // 设置响应
        response.send("延时响应");
    }, 3000);
});

app.get("/ie", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");

    // 设置响应
    response.send("HELLO IE");
});

// jQuery服务
app.all("/jQuery-server", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");
    response.setHeader("Access-Control-Allow-Headers", "*");
    const data = { name: "001" };
    response.send(JSON.stringify(data));
});

// axios服务
app.all("/axios-server", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");
    response.setHeader("Access-Control-Allow-Headers", "*");
    const data = { name: "001" };
    response.send(JSON.stringify(data));
});

app.all("/json-server", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");

    // 响应头  '*'表示所有的头信息 都可以接受
    response.setHeader("Access-Control-Allow-Headers", "*");

    // 响应一个数据
    const data = {
        name: "atuigu",
    };
    // 对对象进行字符串转换
    let str = JSON.stringify(data);
    // 设置响应
    response.send(str);
});

// jspnp服务
app.all("/jsonp-server", (request, response) => {
    // response.send('console.log("hello jsonp")');
    const data = {
        name: "ludan",
    };
    let str = JSON.stringify(data);
    // 返回结果

    response.end(`handle(${str})`);
});

// username
app.all("/jquery-jsonp-server", (request, response) => {
    const data = {
        name: "ludan",
        city: ["汕头", "深圳", "广州"],
    };
    // 将数据返回转化为字符串
    let str = JSON.stringify(data);
    // 接受callbvack参数
    let cb = request.query.callback;
    // 返回结果
    response.end(cb + `(` + str + `)`);
});
// 4、监听端口启动服务
app.listen(8000, () => {
    console.log("服务器已经启动,8000 端口监听中....");
});

终端输如 node server.js

POST请求

参数在send方法中

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Ajax POST 请求</title>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: solid 1px #999;
        }
    </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");
            // 3、发送
            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>

server.js在上文中的get方法中有

AJAX设置请求头

将上述代码server.js 中的post 改成all

在绑定事件中添加

 // 设置请求头
            xhr.setRequestHeader(
                "Content-Type",
                "application/x-www-form-urlencoded"
            ); //固定写法

            xhr.setRequestHeader("name", "atguigu");

服务端响应json数据

send方法只接受字符串或者数;所以要进行数据转化

<head>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: solid 1px #333;
        }
    </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;
                        // 手动对数据转化
                        /**let data = JSON.parse(xhr.response);
                                     console.log(data);
                                     result.innerHTML = data.name;
                                    */

                        console.log(xhr.response);
                        // 自动转换
                        result.innerHTML = xhr.response.name;
                    }
                }
            };
        };
    </script>
</body>

server.js的改变 添加以下代码

app.all("/json-server", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");

    // 响应头  '*'表示所有的头信息 都可以接受
    response.setHeader("Access-Control-Allow-Headers", "*");

    // 响应一个数据
    const data = {
        name: "atuigu",
    };
    // 对对象进行字符串转换
    let str = JSON.stringify(data);
    // 设置响应
    response.send(str);
});

nodemon自动重启工具

在终端输入

npm install -g nodemon

AJAX请求异常与网络超时

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        #result {
            width: 200px;
            height: 100px;
            border: solid 1px sienna;
        }
    </style>
</head>

<body>
    <button>点击发送</button>
    <div id="result"></div>
    <script>
        const btn = document.getElementsByTagName("button")[0];
        const result = document.getElementById("result");
        btn.addEventListener("click", function() {
            const xhr = new XMLHttpRequest();

            // 超时设置
            xhr.timeout = 2000;

            // 超时回调
            xhr.ontimeout = function() {
                alert("加载出错");
            };
            // 网络异常的回调
            xhr.onerror = function() {
                alert("你的网络似乎跑路了");
            };
            // 2、初始化 设置类型与URL
            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>

AJAX取消请求

  <button>点击发送</button>
    <button>点击取消</button>
    <script>
        // 获取对象
        const btn = document.querySelectorAll("button");

        let x = null;
        btn[0].onclick = function() {
            x = new XMLHttpRequest();
            x.open("GET", "http://127.0.0.1:8000/delay");
            x.send();
        };

        // 取消
        btn[1].onclick = function() {
            x.abort();
        };
    </script>

Ajax重复发送请求

 <button>发送请求</button>
    <script>
        // 获取对象
        const btn = document.querySelectorAll("button");

        let x = null;
        // 标识变量
        let isSending = false; //是否正发送AJAX请求
        btn[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;
                }
            };
        };
    </script>

jQuery中的AJAX

get请求

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

post请求

$.post(url,[data],[callback],[type])
	url:请求的URL地址
	data:请求携带的参数
	callback:载入成功时的回调函数

jQuery发送Ajax请求

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link crossorigin="anonymous" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap-grid.min.css" />
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/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">通用型方法</button>
    </div>
    <script>
        $("button")
            .eq(0)
            .click(function() {
                $.get(
                    "http://127.0.0.1:8000/jQuery-server", {
                        a: 100,
                        b: 200,
                        c: 300,
                    },
                    function(data) {
                        console.log(data);
                    },
                    "json"
                );
            });
        $("button")
            .eq(1)
            .click(function() {
                $.post(
                    "http://127.0.0.1:8000/jQuery-server", {
                        a: 100,
                        b: 200,
                        c: 300,
                    },
                    function(data) {
                        console.log(data);
                    }
                );
            });
    </script>
</body>

Axios

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script crossoring="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.24.0/axios.min.js"></script>
</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() {
            axios
                .get("/axios-server", {
                    // url参数
                    params: {
                        id: 100,
                        vip: 7,
                    },
                    // 设置请求头信息
                    headers: {
                        name: "foobar",
                    },
                })
                .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: 130,
                        },
                        // 请求体
                    }
                )
                .then((value) => {
                    console.log(value);
                });
        };
        btns[2].onclick = function() {
            axios({
                // 请求方法
                method: "POST",
                // url
                url: "/axios-server",
                // utl 参数
                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);
            });
        };
    </script>
</body>

</html>

server.js添加

// axios服务
app.all("/axios-server", (request, response) => {
    // 设置响应头   设置允许跨域
    response.setHeader("Access-Control-Allow-Origin", " *");
    response.setHeader("Access-Control-Allow-Headers", "*");
    const data = { name: "001" };
    response.send(JSON.stringify(data));
});

fetch函数发送ajax请求

<button>发送</button>
    <script>
        const btn = document.querySelector("button");
        btn.onclick = function() {
            fetch("http://127.0.0.1:8000/axios-server?vip=10", {
                    // 请求方法
                    method: "POST",
                    // 请求头
                    headers: {
                        name: "ludan",
                    },
                    //请求体
                    body: "usernam=admin&&password=admin",
                })
                .then((response) => {
                    return response.json();
                })
                .then((response) => {
                    console.log(response);
                });
        };
    </script>

server.js添加以下代码

HTTP

HTTP协议请求报文与响应文本结构

http(hypertext transport protocol) 协议【超文本传输协议】,协议详细规定了浏览器和万维网服务器直接按互相通信的规则。

约定,规则

请求报文

重点是格式与参数


POST …/ s?ie=utf-8 HTTP/1.1

Content-type: text/html;charset=utf-8 格式要掌握 ,名字+冒号+空格+值

​ Content-length:2048

​ Content-enoding:gzip

空行 空行必须有

	<head>
	    <body>
            <h1>
                卤蛋
            </h1>
        </body>
	</head>

​ (若为post是必需的,get不是必需的)


响应报文


HTTP/1.1 200 OK

Host: atguigu.com 格式要掌握 ,名字+冒号+空格+值

​ Cookie: name=guigu

​ Content-type: application/x-www-form-urlencoded

​ User-Agent: chrom 83

空行

username=admin&passwordadmin (若为post是必需的,get不是必需的)


*404

*403

*403

*500

*200

Express框架的介绍与基本使用

Express基于Nodes.js平台,快速、开放、极简的Web开发框架

// 1、引入express
const express = require("express");

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

// 3、创建路由规则
/**
 *  request 是对请求报文的封装
 *  respon  是对响应报文的封装
 */
app.get("/", (request, response) => {
    // 设置响应
    response.send("HELLO EXPRESS");
});

// 4、监听端口启动服务
app.listen(8000, () => {
    console.log("服务器已经启动,8000 端口监听中....");
});

终端操作

https://pic3.zhimg.com/80/v2-b3f9b80ef4dae93b3f906605b4e6432a_720w.jpg

https://pic3.zhimg.com/80/v2-a7f77e976647f9ffe10ba98227cafe0a_720w.jpg

https://pic4.zhimg.com/80/v2-73ee9d768174ed6e708513ac49cf7b77_720w.jpg

浏览器

https://pic4.zhimg.com/80/v2-8224900ae76e2a2a79a0a706565fe4d3_720w.jpg

跨域

出现跨域的原因

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 否 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)

非同源限制

【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

【2】无法接触非同源网页的 DOM

【3】无法向非同源地址发送 AJAX 请求

同源策略

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

违背同源策略就是跨域

注意要在127.0.0.1:9000/home端口打开

<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>

在文件中新建server.js

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("服务已经启动");
});

解决跨域

JSONP

JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

核心思想:网页通过添加一个

返回的结果要其他语法能识别

<style>
        #result {
            width: 200px;
            height: 100px;
            border: solid 1px #666;
        }
    </style>
</head>

<body>
    <div id="result"></div>
    <script>
        // 处理数据
        function handle(data) {
            // 获取元素
            const result = document.getElementById("result");
            result.innerHTML = data.name;
        }
    </script>
    <!-- <script src="http://127.0.0.1:5500/%E4%BB%A3%E7%A0%81/%E8%B7%A8%E5%9F%9F/JSONP/js/app.js"></script> -->
    <script src="http:127.0.0.1:8000/jsonp-server"></script>
</body>

</html>

在最初的server.js中添加

// jspnp服务
app.all("/jsonp-server", (request, response) => {
    // response.send('console.log("hello jsonp")');
    const data = {
        name: "ludan",
    };
    let str = JSON.stringify(data);
    // 返回结果

    response.end(`handle(${str})`);
});

cors

CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin

2、带cookie跨域请求:前后端都需要进行设置

【前端设置】根据xhr.withCredentials字段判断是否带有cookie
原生ajax

var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
 
// 前端设置是否带cookie
xhr.withCredentials = true;
 
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');
 
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
        alert(xhr.responseText);
    }
};

**② jQuery ajax **

$.ajax({
   url: 'http://www.test.com:8080/login',
   type: 'get',
   data: {},
   xhrFields: {
       withCredentials: true    // 前端设置是否带cookie
   },
   crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
});
 
 

③vue-resource

Vue.http.options.credentials = true

④ axios

axios.defaults.withCredentials = true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值