JS开发实战:跨域那点事(完结篇)

以前笔者也写过关于跨域的文章(链接在文末放出),但从未停止过对【跨域】的探索。近日又偶然得到了关于跨域的一些见解和知识,觉得将其总结一下。


众所周知,对于【跨域】,最简单、最便捷的方法莫过于CORS——这是一种后端设置跨域的方式。

为了支持cors,设置Access-Control-Allow-Origin头为*,如下所示:

const http=require('http');

var server=http.createServer(function(req,res){
	res.setHeader('Access-Control-Allow-Origin','*');
	res.writeHead(200);
	res.end('Hello cors-mxc');
});
server.listen(8081);

前面,我还说过关于Ajax的四种常用请求方式post、get、put、delete
现在有一个问题:用put请求来标记一次更新,而不是用get或post进行跨域ajax请求。怎么办?浏览器貌似不喜欢这种动作。。。

要知道:要使用get、post、head之外的一个方法,必须对你的请求进行【预绘】——它的修改也是服务器端的。
具体来说,我们要设置Access-Control-Allow-Methods头部,以反映出你所需支持的http动词:

res.setHeader('Access-Control-Allow-Methods','GET,PUT,POST,DELETE,OPTIONS');

我们顺便发现了“options”:这是我们感兴趣的动词之一。
当使用一个put做出ajax请求,XMLHTTPRequest对象首先会发送options请求,以搞清楚服务器上是否支持put请求。在服务器上,代码通过返回一个204状态码来响应options请求。然后,浏览器发送put请求处理数据。


前面我们还说了通过ajax发送二进制数据并加载到图像中

要想通过ajax,以二进制数据的形式获取一个服务器端的图像。只需将responseType设置为blob,然后当数据返回的时候操作它。
如下,我们转换了数据并且将其加载到一个img元素中:

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>CORS blob</title>
	</head>
	<body>
		<img id="result" />
		<script>
			var request=new XMLHttpRequest();
			
			request.open('GET','mxcdwx.png',true);
			request.responseType="blob";
			var img=document.getElementById("result");
			request.onload=function(event){
				var blob=request.response;
				img.src=URL.createObjectURL(blob);
			};
			request.send();
		</script>
	</body>
</html>

CORS的另一优点就是,它支持Ajax请求中的二进制数据(也被称为类型数组),一个二进制请求的关键要求是,将reponseType设置为如下值之一:
arraybuffer——固定长度的原始二进制数据缓存
blob——类似文件的不可变原始数据

在上述代码中,笔者使用URL.createObjectURL()方法把blob转换为一个DOMString(通常映射为JavaScript字符串),带有传递的对象的URL,该URL赋值给img元素的src属性——一旦图像加载了,代码调用URL.revokeObjectURL()(自带API)来释放URL。


哦今天的重点是这个:跨域共享http-cookies

这个必须在客户端和服务器端都做出修改,才能支持可信任的请求。

在客户端,必须在XMLHttpRequest对象上设置withCredentials属性:

var request=new XMLHttpRequest();
request.onreadystatechange=function(){
	if(this.readyState===4){
		console.log(this.status);
		if(this.status===200){
			document.getElementById("result").innerHTML=this.responseText;
		}
	}
};
request.open('GET','http://burningbird.net:8081/');
request.withCredentials=true;
request.send(null);

而在服务端,必需将Access-Control-Allow-Credentials头部设置为true

const http=require('http');

var server=http.createServer(function(req,res){
	res.setHeader('Content-type','text/plain');
	res.setHeader('Access-Control-Allow-Origin','http://somedomain.com');
	res.setHeader('Access-Control-Allow-Credentials',true);
	
	var cookies=new Cookies(req,res);
	cookies.set('apple',"red");
	
	res.writeHead(200);
	res.end('Hello cors-mxc');
});
server.listen(8081);

能够跨域发送http-cookie或认证,这就是另一项cors扩展了。
这里为什么Access-Control-Allow-Origin要设置为确定值
因为通配符*可能会被某些浏览器阻拦,从而使发送失败!


笔者相关博文:

  1. 前端常用的几种跨域通信方式实践:jsonp&cors&postMessage
  2. 【Ajax】跨域的产生及如何解决跨域问题
  3. (JavaScript)百度/Google 搜索的即时自动补全功能究竟是如何“工作”的?
发布了195 篇原创文章 · 获赞 391 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43624878/article/details/104022735
今日推荐