跨域问题

引言

跨域,顾名思义,就是一个域发送请求访问另一个域。

什么是域?

域就是协议名(如http)+主机名(如www.baidu.com)+端口号(如80)。只有这三部分一样,才能算是同一个域

跨域的方法常用的有四种:分别是JSONP、iframe标签跨域、代理服务器跨域、CORS跨域

JSONP跨域

众所周知,在HTML页面中的< img >、< link >、< script >等标签的src属性是不受跨域请求限制。所以我们可以通过动态生成

// 动态创建script标签
var script = document.createElement('script');
// 随机生成函数名,不然会读取本地缓存的js文件
var time = new Date();
var funcName = 'jsonp'+time.getTime();

// 拼接URL,判断URL中是否传有参数
if(url.indexOf('?')>0){
    // 如果url中传有参数,这样拼接URL
    url = url + '&callback' + funcnName;
}else{
    // 如果url中没有参数,这样拼接URL
    url = url + '?callback' + funcnName;
}

// 注册回调函数到全局
window[funcName] = function(data){
    callback(data);  // 这里的回调函数自己设定
    //调用完回调函数后销毁我们注册的函数和创建的script标签
    delete window[funcName];
    script.parentNode.removeChild(script);
}


// 设置script标签的src属性
script.setAttribute('src',url);
// 把script标签加入head,请求服务器得到数据
document.getElementsByTagName('head')[0].appendChild(script);

使用JSONP需注意

要注意回调函数的名称。我们需要和后台确定一个callback参数(作确定回调函数名用),方便后台调用前端写的回调函数

JSONP的缺点

①无法发送POST请求
②想确定JSONP请求是否失败并不容易,大多数确定方法都是结合超时时间来判断
③JSONP是可执行脚本,可能存在安全隐患
④对于一些第三方API接口,他们不像和我们约定好的后台那样会读取callback参数。他们只返回JSON或者XML数据,也就是我们平常像后台要的数据一样,只是他是跨域的。这种时候,JSONP形式获取数据就不合适了

iframe标签跨域

这个方法的关键在于window的name属性。该属性的特性在于,同个窗口的所有页面使用的都是同一个window.name属性,并且不会因为刷新和新页面的载入而重置,但是每个页面都可以读取和修改这属性!所以我们可以使用这个属性作为中介,存放接收的数据

// 客户端




// 只是利用iframe获取跨域数据,所以样式设置不显示


// 服务端

app.get('/xxx/xxx/index',function(req,res){
   let param = req.query.name;
   var data = {name:param};
   var data = JSON.stringify(data);
   
   res.send('');
});

iframe标签跨域缺点

不支持POST访问

代理服务器处理跨域

我们需要知道的是,跨域问题只存在于浏览器中,服务器之间的访问不存在跨域问题。所以我们可以通过后台访问需要跨域访问的url,然后让后台返回数据给前端就行了。

CORS跨域

其是W3C推出的一种新机制,基于浏览器的一个内置机制,需要浏览器支持。所以其实现方法只需要和正常的AJAX一样,不需要额外的代码,浏览器支持该机制的话,就会自动帮你跨域,不支持就会报错。但需要满足以下要求

  • 请求方式要用:HEAD、POST、GET
  • 数据类型 Content-Type 只能是application/x-www-form-unlencoded、multipart/form-data或text/plain中的一种
  • 不使用自定义的请求头

你可能感兴趣的:(JS)