002前后端交互

本文详细介绍了AJAX封装、长链接与WebSocket的区别,以及在前后端交互中的应用场景,包括同步与异步上传、下载、文件合并与切割,还探讨了JSONP和CORS解决跨域问题的方法,以及RestfulAPI的设计原则。
摘要由CSDN通过智能技术生成

前后端交互

ajax

ajax封装

function req({
	method='get',
	url,
	data,
	headers,
	responseType
}) {
	return new Prmise((resolve, reject) => {
		let xhr = new XMLHttpRequest();
		console.log(xhr.readyState)  // 0 (未初始化)还没有调用send()方法  (没有开始)

        xhr.open(method, url);
        console.log(xhr.readyState)  // 1 (载入)已调用send()方法,正在发送请求  (正在发送中)

        for(let key in headers) {
            xhr.setRequestHeader(key, headers[key]);
        }
        
        if(responseType){
        	xhr.responseType = responseType;
        }
        
        if(typeof data === 'object') {
        	data === JSON.stringify(data);
        	xhr.setRequersHeader('Content-Type', 'application/json;charset=UTF-8')
        }

        if(data) {
            xhr.send(data);
        }else {
            xhr.send();
        }
        console.log(xhr.readyState)  // 1 (载入)已调用send()方法,正在发送请求  (正在发送中)

		// onreadystatechange  状态改变都会触发
        xhr.onreadystatechange = function() {
            console.log(xhr.readyState)  // 依次输入 2、3、4 
            // 2、(载入完成)send()方法执行完成 (已发送)
            // 3、(交互)正在解析相应内容  (正在响应中)
            // 4、(完成)响应内容解析完成,可以在客户端调用  (结束响应)

            if(xhr.readyState === 4) {
            	if(xhr.status === 200) {
            		resolve(xhr.response);
            	}else {
            		reject(xhr.response);
            	}
            }
        }
	})
}

async function run() {
	let res = await req({
		url: '/index.html',
	})
	console.log(res)
}

run()

长链接

一直返回xhr.readyState === 3 状态

长链接与ws区别:

​ 长链接:在http协议下类似摆脱【先请求后响应】模型的一种方式,实现【服务器长时间主动向客户端通信】的效果 一次请求多次响应

​ ws: 全双工通信 不受服务器 客户端数显,谁多发的限制 任意请求响应

聊天室实现方式:

​ 1、轮询ajax;

​ 2、服务器长链接;

​ 3、websocket;

​ 4、Socket.io (根据兼容性封装以上三种交互方式)

上传

同步上传

浏览器默认发生的行为 上传成功后存在跳转

<form action="/upload" method="post" enctypr="multipart/form-data">
	<input type="file" name="file"/>
	<button>上传</button>
</form>
异步上传
<input id="file" type="file" name="file"/>
<button id="ajaxAsyncUpload">上传</button>

ajaxAsyncUpload.onclick = funciton(){
	let f1 = file.files[0];
	
	// 创建容器(H5之后)
	let fd = new FormData();
	fd.append('file', f1);
	
	req({
		url: '/upload',
		method: 'post',
		data: fd,
	})
}

下载

同步下载
<a href="/11.txt" download="download.txt">同步下载</a>
异步下载
<button id="ajaxAsyncDownload">下载</button>

function downloadForTag(blob, filename) {
	// 内存地址指向文件
	let url = window.URL.createObjectURL(blob);
	
	// 创建a标签赋值url
	let a = document.createElement('a');
	a.href = url;
	// 不指定download 就跳转了
	a.download = filename;
	a.style.display = 'none';
	
	// 插入元素
	document.body.appendChild(a);
	
	// 点击a标签
	a.cliclk();
	
	// 释放资源
	a.remove();
	window.URL.revokeObjectURL();
}

ajaxAsyncDownload.onclick = async funciton(){
	let blobRes = await req({
		url: '/11.txt',
		// blob 前端封装的一个文件容器
		// responseType可用: text arraybuffer  blob
		responseType: 'blob'
	});
	
	downloadForTag(blobRes, 'download.txt')
}

文件合并

<button id="fileJoin">合并</button>

fileJoin.onclick = async funciton(){
	let res = await req({
		url: '/chunkfile',
		responseType: 'blob'
	});
	
	// arrayBuffer: blob文件对象底层的容器
	let arrayBuffer = await res.arrayBuffer();
	
	// 拼接双倍
	downloadForTag(new Blob([arrayBuffer, arrayBuffer]), '合并.txt')
}

文件切割

<button id="fileSplit">切割</button>

fileSplit.onclick = async funciton(){
	let res = await req({
		url: '/chunkfile',
		responseType: 'blob'
	});
	
	let arrayBuffer = await res.arrayBuffer();
	
	let len = arrayBuffer.bytelength/2;
	
	fo(let i = 0; i < arrayBuffer.bytelength; i+= len) {
		downloadForTag(new Blob([arrayBuffer.slice(i, i+len)]), `切割${i}.txt`)
	}
}

跨域

同源策略: 针对于ajax 发起网站 与 接口访问网站 的一种限制

协议、接口、域名不一致都会引起跨域

解决方式:

​ 1、jsonp(利用外链请求【img(jpg) script(js) link(css) iframe(html)】非ajax不受限制的特点来实现);

​ 2、CORS(后端让浏览器不要多管闲事);

​ 3、代理(当前页面服务器帮助外面转发,不存在跨域之说)

JSONP

一种处理跨域的方式 和json没有多大关系

数据传输是json数据

利用外链非ajax不受同源策略影响实现站外js执行,并传递数据

只能是get请求 前端和后端都需要coding

优点:利用浏览器外链,兼容性好

缺点:只能get请求;代码前端后端都需要编写

<script>
	function myJsonP(url, fn) {
		// 1、动态创建script标签
		let script = document.createElement('script');
		// 1.5 定义动态的方法名
		let fnName = 'callbackName_' + Date.now();
		// 2、设置src
		script.src = url +  '?callback=' + fnName;
		// 2.5 声明方法名
		window[fnName] = function(data) {
			// 4、使用完毕 释放资源
			script.remove();
			delete window[fnName];
			fn(data);
		}
		// 3、插入到文档中
		document.body.appendChild(script);
	}
	
	function myJsonP_promise(url) {
		return new Peomise((res,rej) => {
			// 1、动态创建script标签
            let script = document.createElement('script');
            // 1.5 定义动态的方法名
            let fnName = 'callbackName_' + Date.now();
            // 2、设置src
            script.src = url +  '?callback=' + fnName;
            // 2.5 声明方法名
            window[fnName] = function(data) {
                // 4、使用完毕 释放资源
                script.remove();
                delete window[fnName];
                res(data);
            }
            // 3、插入到文档中
            document.body.appendChild(script);
		})
	}
</script>

<script>
	myJsonP('http://localhost:4567/jsonp' ,(data) => {
		console.log(data)
	})
	
	async function run() {
		let res = awiat myJsonP_promise('http://localhost:4567/jsonp')
		console.log(res)
	}
</script>
CORS

跨站资源共享

1、让后端允许访问的域名: Access-Control-Allow-Origin: * (最好为动态对方ip地址)

​ CORS场景下如果使用cookie不能写*

2、Access-Control-Allow-Methods

3、Access-Control-Allow-Headers 若有自定义请求头需要在这声明

4、允许携带cookie: Access-Control-Allow-Credentials: true

​ 客服端也需要设置允许跨域携带cookie: withCredentials: true

优点:支持各种请求方式

缺点:兼容性差点,不够安全(全网暴露资源)

代理

正向代理(为客户端服务):隐藏了客户端;反向代理(为服务端服务):隐藏了服务器ip,客户端不知道服务器ip

优点:无兼容性;支持各种请求方式,相对安全

RestFul

高效前后端开发的约定;提供一个模块名;剩下的用get/post/delete/put/patch请求方式分别完成不太的行为

get:获取

post:新增

delete:删除

put:全量更新

patch:增量更新

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值