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

发布于:2023-01-25 ⋅ 阅读:(595) ⋅ 点赞:(0)

客户端的数据配置解析

搭建一个最简单的服务器

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

创建一个最简单的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);
}
function Ajax(data){
    return new Promise((resolve,reject)=>{
        xhr = new XMLHttpRequest();
        xhr.open("POST","http://localhost:3000");
        xhr.send(data);
        xhr.onload = function(){
            resolve(xhr.response)
        }
    })
}

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

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

参数: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编码格式
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

参数: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)
}

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

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

服务端的接收数据的解析

方法 功能
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);
            //<Buffer 68 64 68 e4 bd a0 e5 a5 bd>
            data +=_chunk});
        req.on("end",()=>{resolve(data)})
    })
}

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

这种方式,每次只能写入一个响应头,但是可以写入多个
而且使用SetHeader使用时必须写在WriteHead之前,在WriteHead之后不能使用SetHeader
res.setHeader("Access-Control-Allow-Origin","*")

如果自定义的响应头,需要在客户端获取,就需要设置 "Access-Control-Expose-Headers":["X-Name"]

也就是说这个服务器响应头内容,在客户通过 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"]
})
content-type: text/html;charset=utf-8
x-name: xietian
x-set-cookie: a=1

设置超时

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();
}

加载进度

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)+"%");
}  

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

}

使用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())
}


把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+"通信地址错误")
        }
    })
}
init();
async function init(){
    var res=await ajax("http://localhost:4001",{
        method:"post",
        body:"aaa"
    })
}
本文含有隐藏内容,请 开通VIP 后查看