• 解析ajax服务请求——客户端的数据配置解析——服务端node的接收数据的解析——其他状态——fetch——ajax封装fetch


    客户端的数据配置解析

    搭建一个最简单的服务器

    var http = require("http");
    http.createServer(function(req,res){
        res.writeHead(200, {
            "Content-Type": "text/html;charset=utf-8",
            "Access-Control-Allow-Origin": "*" //CORS 允许谁跨域访问
        })
        res.end("ok")
    }).listen(3000,"10.9.46.184",function(){
        console.log("服务器已开启");
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建一个最简单的ajax服务请求

    var xhr = new XMLHttpRequest();
    xhr.addEventListener("load",loadHandler);
    xhr.open("POST","http://10.9.46.184:3000");
    xhr.send("hdh");
    
    function loadHandler(e){
        console.log(xhr.response);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    解析在ajax的open方法中的参数

     xhr.open(Method,URL,async,user,password)
    
    • 1

    参数:Method:请求方法

    • GET:
    • POST

    GET:重点在于我接收服务端的信息
    POST:重点在于我客户端发送到服务器数据

    • GET在浏览器回退时是无害的,而POST会再次提交请求。

    • GET产生的URL地址可以被Bookmark(记录),而POST不可以。

    • GET请求会被浏览器主动cache(缓存),而POST不会,除非手动设置。

    • GET请求只能进行url编码,而POST支持多种编码方式。

    • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

    • GET请求在URL中传送的参数是有长度限制的,而POST么有。

    对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

    • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

    • GET参数通过URL传递,POST放在Request body中。 GET产生一个TCP数据包;POST产生两个TCP数据包。

    • 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

    • PUT
    • DELETE

    不需要考虑跨域问题,但是用这两个来访问服务器就得,考虑方法跨域问题。
    在这里插入图片描述
    提示服务端我给什么方式发送
    遇到PUT和DELETE,
    必须给响应头增加 Access-Control-Allow-Methods:*


    参数:URL请求路径

    http:// 协议
    localhost 域名
    :4001 端口号
    (/new/inded.html /new 路由/new/index.html 路径) ?a=1&b=2 search
    #ab hash

    • 在ajax请求中path 向node请求时一般不带有文件名,路径就是ajax请求的路由

    • 如果在单页面开发时,#ab这种hash也叫做当前页面的路由

    如果有路由里面有汉字字符信息,服务器解析路由会出现乱码,这是因为 URI 编码格式,现在浏览器一般都会自动将非法字符转换为这种编码,那么就需要

    decodeURIComponent();URI编码格式解析转换为中文
    encodeURIComponent(); 将中文转换为URI编码格式
    
    • 1
    • 2
    xhr.open("GET","http://10.9.46.184:3000/hello你好");
    /hello%E4%BD%A0%E5%A5%BD
    可在node中使用decodeURIComponent(req.url)解析
    /hello你好
    
    ===========================================================
    console.log(req.url);
    console.log(decodeURIComponent(req.url));
    console.log(encodeURIComponent(req.url));
    
    /hello%E4%BD%A0%E5%A5%BD
    /hello你好
    %2Fhello%25E4%25BD%25A0%25E5%25A5%25BD
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    参数:async是否同步异步 ,默认是true,异步

    默认true,是异步执行,通过侦听事件处理通信后的数据
    如果修改false,是同步,但是这样会造成页面白屏

    禁止使用,


    参数user,password

    user和password 当访问某个网站时,需要用户名和密码就需要在这里传入


    知识点:

    当在open中使用GET时,如果地址中使用了文件名,意味着加载这个文件,而不是和某个服务通信
    这样我们完成了加载,这个加载就是加载配置文件

    var xhr=new XMLHttpRequest();
    	xhr.addEventListener("load",loadHandler);
    	xhr.open("GET","http://localhost:5500/ajax/a.json");
    	xhr.send();
    
    
    function loadHandler(e){
    	// console.log(JSON.parse(xhr.response))
    	//文本长度
    	console.log(xhr.response.length)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    如果ajax同时发送两个,第一个就无效了
    相同数据json格式比text文本格式的长度要长
    xml的文本格式,虽然灵活所有语言支持其操作,但是数据冗余更大

    var arr=Array.from(xhr.responseXML.querySelectorAll("man")).filter(item=>item.getAttribute("age")>23);
    arr.forEach(item=>console.log(item))
    //可以对他进行任何节点操作
    
    • 1
    • 2
    • 3

    服务端的接收数据的解析

    方法功能
    req.method客户端请求方式
    put,delete会多请求一次服务器OPTIONS

    客户端请求头和服务器响应头

    请求头必须在open之后,send之前设置
    xhr.setRequestHeader(请求头KEY,请求头值)


    如果自定义请求头信息或者不是在默认的修改请求头信息时,在跨域时必须在响应头中有设置

    "Access-Control-Allow-Headers":"*" 允许头部跨域
    这样设置后服务器中才可以获取到请求头提交的数据
    自定义请求头时,我们希望大家以X起头使用-区分
    例如:X-Name niuniu


    可以通过设置Set-Cookie将cookie信息主动发送到服务端,这样就可以解决因为跨域造成cookie无法发送的问题


    'content-length' 在POST发送数据时,会自动发送一个content-length,告知服务器,当前send发送的数据的长度,这个长度就是buffer数据流的长度。

    function getData(req){
        return new Promise(function(resolve,reject){
            data=''
            req.on("data",(_chunk)=>{
                console.log(_chunk);
                //
                data +=_chunk});
            req.on("end",()=>{resolve(data)})
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    WriteHead所有的响应数据使用同一个响应头
    setHeader可以根据不同的请求头设置不同的响应头
    但是跨域的响应体内容就不会发送到客户端

    这种方式,每次只能写入一个响应头,但是可以写入多个
    而且使用SetHeader使用时必须写在WriteHead之前,在WriteHead之后不能使用SetHeader
    res.setHeader("Access-Control-Allow-Origin","*")
    
    如果自定义的响应头,需要在客户端获取,就需要设置 "Access-Control-Expose-Headers":["X-Name"]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    也就是说这个服务器响应头内容,在客户通过 console.log(xhr.getAllResponseHeaders());//获取所有的响应头这段代码拿到的只有是:

    res.writeHead(200, {
        "Content-Type": "text/html;charset=utf-8",
        "Access-Control-Allow-Origin": "*", //CORS 允许谁跨域访问
        // "Access-Control-Allow-Methods":"*"
        "Access-Control-Allow-Headers": "*",
        "X-Name": "xietian",
        // "X-Set-Cookie": encodeURIComponent(str),
        "X-Set-Cookie": "a=1",
        "Access-Control-Expose-Headers": ["X-Name", "X-Set-Cookie"]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    content-type: text/html;charset=utf-8
    x-name: xietian
    x-set-cookie: a=1
    
    • 1
    • 2
    • 3

    设置超时

    var xhr=new XMLHttpRequest();
    // 超时事件
    xhr.addEventListener("timeout",timeoutHandler);
    xhr.open("GET","http://localhost:4001");
    xhr.timeout=2;//设置超时
    xhr.send();
     
    function timeoutHandler(e){
        console.log("超时")
        xhr.abort();//断开连接
        // 超时重新发送
        xhr.open("GET","http://localhost:4001");
        xhr.send();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    加载进度

    var xhr=new XMLHttpRequest();
    xhr.addEventListener("progress",progresshandler)
    xhr.open("GET","http://localhost:5500/ajax/img/a.jpg");
    xhr.send();
    function progresshandler(e){
        console.log(e);
        // e.loaded: 364 已加载字节
        // e.total: 364  总字节
        console.log((e.loaded/e.total*100).toFixed(2)+"%");
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    xhr状态事件

    var xhr=new XMLHttpRequest();
    xhr.addEventListener("readystatechange",loadHandler);
    xhr.addEventListener("error",errHandler);
    xhr.open("GET","http://localhost:4001");
    xhr.send();
    function loadHandler(e){
        console.log(xhr.status,xhr.readyState);
        //xhr.readyState 当前ajax执行的进度
        if(xhr.readyState===4 && xhr.status===200){
            console.log(xhr.response)
        }else if(xhr.readyState===4){
    
        }
        //当响应头接收时
        if(xhr.readyState===2){
            console.log(xhr.getAllResponseHeaders());
        }
        //向服务器发送的地址,其中包含参数和hash
        console.log(xhr.responseURL)
    }
    
    function errHandler(e){
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    使用fetch

    init();
    async function init(){
        var res=await fetch("http://localhost:4001",{
            method:"POST",
            body:"aa",
            headers:{
                "Content-Type":"appliction/x-www-form-encoded"
            }
        })
        console.log(res)
        console.log(res.headers);//获取响应头
        for(var [key,value] of res.headers){
            console.log(key,value)
        }
            解析服务端响应的文本数据
        console.log(await res.text())
        解析服务端响应的json数据
        SyntaxError: Unexpected token a in JSON at position 0 当前的数据不符合json格式
        console.log(await res.json())
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    把ajax封装成fetch方式

    function ajax(url,{method="get",body,headers}={method:"GET"}){
        return new Promise(function(resolve,reject){
            var xhr=new XMLHttpRequest();
            xhr.open(method,url);
            if(headers){
                for(var key in headers){
                    xhr.setRequestHeader(key,headers[key]);
                }
            }
            body ? xhr.send(body) : xhr.send();
            xhr.onreadystatechange=function(){
                if(xhr.status===200 && xhr.readyState===4){
                    resolve(xhr.response);
                }else if(xhr.readyState===4){
                    reject(xhr.status);
                }
            }
            xhr.onerror=function(){
                reject(xhr.responseURL+"通信地址错误")
            }
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    init();
    async function init(){
        var res=await ajax("http://localhost:4001",{
            method:"post",
            body:"aaa"
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    【轮式平衡机器人】——TMS320F28069片内外设之ePWM
    PriorityQueue 源码解析(JDK1.8)
    figlet - 字符画工具
    音视频开发需要你懂得的 H264 编码原理
    Kettle需求场景复现
    ZooKeeper实现分布式锁
    Vue3从零开始——掌握setup、ref和reactive函数的奥秘
    spring切面编程 之 注解实战
    Golang 小数操作之判断几位小数点与四舍五入
    .NET开源、跨平台的本地日记APP - SwashbucklerDiary
  • 原文地址:https://blog.csdn.net/m0_46672781/article/details/126231734