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

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析ajax服务请求——客户端的数据配置解析——服务端node的接收数据的解析——其他状态——fetch——ajax封装fetch相关的知识,希望对你有一定的参考价值。

ajax

客户端的数据配置解析

搭建一个最简单的服务器

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


解析在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"
    )

以上是关于解析ajax服务请求——客户端的数据配置解析——服务端node的接收数据的解析——其他状态——fetch——ajax封装fetch的主要内容,如果未能解决你的问题,请参考以下文章

18 AjaxJson以及jackson框架解析json的基本应用

JS里AJAX的使用--(服务器与客户端数据交换)

ssm项目之Ajax请求返还json解析

iOS客户端与服务器的数据交互总结

nginx反向代理功能及常用配置

Tomcat的配置文件Server.xml解析