zoukankan      html  css  js  c++  java
  • 看完我的笔记不懂也会懂----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{
             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{
             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','*');
    
  • 相关阅读:
    安卓中像素px和dp的转换
    Android 使用Vector XML文件创建矢量图片资源,editText监听
    动态设置RecyclerView的高度
    EditText一些用法
    各种加密算法比较
    多线程--Task,等待用户输入AutoResetEvent
    AutoCAD二次开发——AutoCAD.NET API开发环境搭建
    Office(Excel、Word)二次开发——VSTO
    个人信息管理PIM——密码管理工具软件
    【矩阵计算】矩阵乘法其一:基础符号和算法
  • 原文地址:https://www.cnblogs.com/fitzlovecode/p/learn_ajax.html
Copyright © 2011-2022 走看看