0
点赞
收藏
分享

微信扫一扫

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 搜索的即时自动补全功能究竟是如何“工作”的?​​


举报

相关推荐

0 条评论