Loading

看完我的笔记不懂也会懂----Ajax

Ajax(Asynchronous JavaScript And XML)

通过ajax浏览器可以像服务器发送异步请求,最大的优势:可以在不刷新网页的情况下,异步的向后台发送请求,在前端接受并展示数据

本次学习所用到的插件

  1. Node.js
  2. NPM
  3. express(简单的web服务器)
  4. nodemon(用于自动重启node服务器)

XML

  1. XML是什么? 有什么用?

    1. XML 被设计用来传输和存储数据
    2. XML 的设计宗旨是传输数据(XML),而非显示数据(HTML)
    3. XML 被设计为具有自我描述性
    4. XML 标签没有被预定义。您需要自行定义标签
  2. 语法:

    <?xml version="1.0" encoding="utf-8">
    <root>
    <!-- 标签可以自由命名 -->
    <name>Fitz</name>   <!-- 必须正确关闭标签 -->
    </root>
    
    <root>
    <!-- 属性必须加引号 -->
    <!-- 尽量不要使用属性 -->
    <name gender="male">Fitz</name>
    <address province="GD">HouJie</address>
    </root>
    
    <root>
    <!-- 这是错误的属性使用方法 -->
    <attr attr1="error" attr2="wrong">属性不应该这样用</attr>
    </root>
    
    <root>
    <!-- 特殊的符号应该使用实体 -->
    <sample>使用实体例如:大于号 &gt;</sample>
    </root>
    

JSON

由于JSON 比 XML 更小、更快,更易解析。所以现在AJAX返回的数据格式多是使用JSON

{
    "name": "Fitz",
    "hobby": "computer science",
    "dream": "good at math"
}

关于AJAX

  1. ajax的优点
    1. 无需刷新页面即可与服务器进行通讯
    2. 允许根据用户事件来更新部分页面内容
  2. ajax的缺点
    1. 没有浏览历史,这就导致不能回退
    2. 存在跨域问题
    3. 对SEO不友好

HTTP协议

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

  • 请求报文

    • 重要格式与参数
    行    ====>  GET/POST  /s?ie=utf-8  HTTP/1.1
    头    ====>  Host: baidu.com
                 Cookie: name=trash
                 content-type: application/x-www-form-urlencoded
                 user-Agent: chrome 83
    空行  ====>
    体    ====>  username=root&password=root
    
  • 响应报文

  • 重要格式与参数

    行    ====>  HTTP/1.1  200  OK
    头    ====>  Host: baidu.com
                 content-type: text/html;charset=utf-8
                 content-length: 2048
    空行  ====>
    体    ====>  <html>
                    <head></head>
                    <body></body>
                </html>
    

AJAX重点之XMLHttpRequest对象

XMLHttpRequest对象作用是前端向服务端发送ajax请求,别接收来自服务端的数据

``` javascript {.line-numbers}
//主要步骤

// 1  创建xhr对象
var xhr = new XMLHttpRequest();

// 2  初始化   设置请求方法 与 URL
xhr.open('GET','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){
            //处理结果
            // console.log(`行 状态码===>${xhr.status}`);
            // console.log(`行 状态字符串===>${xhr.statusText}`);
            // console.log(`头===>${xhr.getAllResponseHeaders()}`);
            // console.log(`体===>${xhr.response}`);
        }else{
             console.log('Some Error !');
            }
    }
```

关于 onreadystatechange与readyState
每当 readyState 改变时,就会触发 onreadystatechange 事件,readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪

服务端 实例

使用插件 express

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

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

//创建路由规则
app.get('/server',(request,response)=>{
    //request  请求报文封装
    //response  响应报文封装

    //设置响应头
    //允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    response.send('成功接收到来自服务端的消息');
})

app.post('/server',(request,response)=>{
    //request  请求报文封装
    //response  响应报文封装

    //设置响应头
    //允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    response.send('成功接收到来自服务端的消息 -post method');
})


app.listen(8000,()=>{
    console.log('服务已经在8000端口启动....');
})

ajax-get 实例

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewpor" content="width=device-width initial-scale=1.0">
<title>Fitz</title>

<style>

    * {
        margin: 0;
        padding: 0;
    }

    #result{
        width: 200px;
        height: 100px;
        border: solid 1px black;
    }

</style>

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

        <script>
            //获取button
            var btn = document.getElementsByTagName('button')[0];
            var result = document.getElementById("result");
            btn.onclick = function(){
                //AJAX步骤

                // 1  创建xhr对象
                var xhr = new XMLHttpRequest();
                // 2  初始化   设置请求方法 与 URL
                xhr.open('GET','http://127.0.0.1:8000/server?name=fitz');
                // 3  发送请求
                xhr.send();
                // 4  事件绑定   处理服务端返回的结果
                xhr.onreadystatechange = function(){
                    if (xhr.readyState === 4){
                        if (xhr.status >= 200 && xhr.status < 300){
                            //处理结果
                            // console.log(`行 状态码===>${xhr.status}`);
                            // console.log(`行 状态字符串===>${xhr.statusText}`);
                            // console.log(`头===>${xhr.getAllResponseHeaders()}`);
                            // console.log(`体===>${xhr.response}`);



                            //展示在前端div中
                            result.innerHTML = xhr.response;
                        }else{
                            console.log('Some Error !');
                        }
                    }
                }
            }
        </script>
    </body>
</html>

ajax-post 实例

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewpor" content="width=device-width initial-scale=1.0">
<title>Fitz</title>

<style>

    * {
        margin: 0;
        padding: 0;
    }

    #result{
        width: 200px;
        height: 100px;
        border: solid 1px black;
    }

</style>

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

        <script>
            //获取button
            var btn = document.getElementsByTagName('button')[0];
            var result = document.getElementById("result");
            btn.onclick = function(){
                //AJAX步骤

                // 1  创建xhr对象
                var xhr = new XMLHttpRequest();
                // 2  初始化   设置请求方法 与 URL
                xhr.open('POST','http://127.0.0.1:8000/server');
                // 3  发送请求
                xhr.send('name=Fitz&gender=Male');  //post请求参数应在send方法中添加
                // 4  事件绑定   处理服务端返回的结果
                xhr.onreadystatechange = function(){
                    if (xhr.readyState === 4){
                        if (xhr.status >= 200 && xhr.status < 300){
                            //处理结果
                            // console.log(`行 状态码===>${xhr.status}`);
                            // console.log(`行 状态字符串===>${xhr.statusText}`);
                            // console.log(`头===>${xhr.getAllResponseHeaders()}`);
                            // console.log(`体===>${xhr.response}`);



                            //展示在前端div中
                            result.innerHTML = xhr.response;
                        }else{
                            console.log('Some Error !');
                        }
                    }
                }
            }
        </script>
    </body>
</html>

设置请求头信息

// 2  初始化   设置请求方法 与 URL
xhr.open('POST','http://127.0.0.1:8000/server');
//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 3  发送请求
xhr.send('name=Fitz&gender=Male');

服务端响应JSON数据

方法一

前端代码

var div = document.getElementById('result');
    window.onkeydown = function(){
        //发送请求
        var xhr = new XMLHttpRequest();
        xhr.open('GET','http://127.0.0.1:8000/server');
        xhr.send();
        xhr.onreadystatechange = function(){
            if (xhr.readyState === 4){
                if (xhr.status >= 200 && xhr.status < 300){
                    //方法一
                    //通过手动转换来响应JSON
                    let data = JSON.parse(xhr.response);
                    console.log(data);
                    div.innerHTML = data.username;
                }
            }
        }
    }

方法二
前端代码

var div = document.getElementById('result');
    window.onkeydown = function(){
        //发送请求
        var xhr = new XMLHttpRequest();
        xhr.open('GET','http://127.0.0.1:8000/server');
        xhr.send();
        xhr.onreadystatechange = function(){
            if (xhr.readyState === 4){
                if (xhr.status >= 200 && xhr.status < 300){
                    //方法二
                    //自动转换
                    console.log(xhr.response);
                    div.innerHTML = xhr.response.username;
                }
            }
        }
    }

后端代码

//引入express
const express = require("express");
const { json } = require("body-parser");

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

// //创建路由规则
app.all('/server',(request,response)=>{
    //request  请求报文封装
    //response  响应报文封装

    //设置响应头
    //允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    response.setHeader('Access-Control-Allow-Header','*')

    //要发送回去前端的数据
    const data = {
        username: 'root',
        password: 'root123'
    }

    const data2str = JSON.stringify(data);  //手动将data对象转换为JSON字符串
    response.send(data2str);    //send方法只能接收一个字符串
})


app.listen(8000,()=>{
    console.log('服务已经在8000端口启动....');
})

AJAX关于在IE中的缓存问题

解决方法:使用时间戳以保证每次的URL都不一样(参数不一样)

var xhr = new XMLHttpRequest();
xhr.open("GET",'http://127.0.0.1:8000/ie?t'+Date.now());  //使用时间戳
xhr.send();
xhr.onreadystatechange = function(){
    if (xhr.readyState === 4){
        if (xhr.status >= 200 && xhr.status < 300){
            div.innerHTML = xhr.response;  //把结果在前端显示
        }
    }
}

超时设置、回调与网络异常的回调

var xhr = new XMLHttpRequest();
//设置超时
xhr.timeout = 2000;
//设置超时回调
xhr.ontimeout = function(){
    console.log('你的网络似乎有些慢');
}
//设置断网回调
xhr.onerror = function(){
    console.log('你的网络似乎有些问题');
}
xhr.open("GET",'http://127.0.0.1:8000/cancel);  //使用时间戳
xhr.send();
xhr.onreadystatechange = function(){
    if (xhr.readyState === 4){
        if (xhr.status >= 200 && xhr.status < 300){
            div.innerHTML = xhr.response;  //把结果在前端显示
        }
    }
}

取消ajax请求

var btn = document.getElementById('btn');
var btn2 = document.getElementById('btn2');
var div = document.getElementById('result');

var xhr = null;

addEventListener('click',function(){
    if(xhr){
        xhr.abort();
    }
    xhr = new XMLHttpRequest();
    xhr.open("GET",'http://127.0.0.1:8000/cancel');
    xhr.send();
    xhr.onreadystatechange = function(){
        if (xhr.readyState === 4){
            if (xhr.status >= 200 && xhr.status < 300){
                div.innerHTML = xhr.response;  //把结果在前端显示
            }
        }
    }
})

btn2.onclick = function(){
    xhr.abort();
}

jquery发送ajax请求

$(function(){
//get
$('button').eq(0).click(function(){
    $.get('http://127.0.0.1:8000/jquery',
        {
            name: 'fitz',
            age: 20
        },
    function(data){
        console.log(data);
    },'json')
})

//post
$('button').eq(1).click(function(){
    $.post('http://127.0.0.1:8000/jquery',
        {
            name: 'fitz',
            age: 20
        },
        function(data){
            console.log(data);
        })
})

//通用方法
$('button').eq(2).click(function(){
    $.ajax({
        //url
        url: 'http://127.0.0.1:8000/jquery',
        //要发送的参数
        data: {
            a: 'a',
            b: 'b'
        },
        //ajax请求类型
        type: 'GET',
        //指定响应体的类型
        dataType: 'json',
        //设置超时时间
        timeout: 2000,
        //成功的回调
        success: function(data){
            console.log(data);
        },
        //失败的回调
        error: function(e){
            console.log(e);
        },
        //设置头部信息
        headers: {
            a: 200
        }
    })
})

fetch函数发送ajax请求

fetch('http://127.0.0.1:8000/fetch?test=ok',
    {
        //请求方法
        method: 'POST',
        //请求头
        headers: {
            name: 'Da'
        },
        //请求体
        body: 'username=tri4123'
    }).then((response)=>{
            console.log(response);
            return response.text();
            //可以自动解析响应体为JSON格式的数据
            // return response.json();
        }).then((response=>{
            console.log(response);
        })
);

跨域

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

违背同源策略的称之为跨域

解决跨域
使用具备跨域特性的标签:<img> <script> <link> <iframe>

  1. 使用jsonp:在前段定义处理函数,供后端调用

    前端代码

    //在前段设置处理函数,供后端调用
    <script>
        //处理数据的函数
    function handleData(data){
    //获取result元素
    var result = document.getElementById('result');
    result.innerHTML = data.name;
    }
    </script>
    
    
    <!-- <script src="./jsonp.js"></script> -->
    <script src="http://127.0.0.1:8000/jsonp-server"></script>
    

    后端代码

    const express = require("express");
    const app = express();
    app.all('/jsonp-server',(request,response)=>{
    var PersonInfo = {
        name: 'Lx'
    }
    
    //调用前端已经定义好的函数
    //就能将后端数据跨域传给前端
    response.end(`handleData(${JSON.stringify(PersonInfo)})`)
    // response.send('console.log("jsonp实验成功")')
    })
    
  2. jquery(原理还是jsonp)

    前端代码

    
    //callback=?  参数是必须的,这会在前端注册一个函数  供后端调用
    $.getJSON('http://127.0.0.1:8000/server?callback=?',function(){
        //后端的数据....
    })
    

    后端代码

    const express = require("express");
    const app = express();
    app.all('/server',(request,response)=>{
    var PersonInfo = {
        name: 'Lx'
    }
    
    //获取在前端注册的callback函数
    var callbackFunc = request.query.callback;
    
    //调用前端已经定义好的函数
    //就能将后端数据跨域传给前端
    response.end(`${callbackFunc}(${JSON.stringify(PersonInfo)})`);
    })
    
  3. CORS 跨域资源共享 官方的跨域方案

CORS通过在服务端设置一个响应头告诉前端,该请求是否允许跨域,浏览器收到响应头后会对响应进行放行

后端代码

//允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
response.setHeader('Access-Control-Allow-Methods','*');
posted @ 2020-10-18 00:24  虚伪渲染敷衍  阅读(104)  评论(0编辑  收藏  举报