12

金三银四,换工作大季,这段时间应该不少被面到怀疑人生的孩子,就包括本宝宝。
为了下次面试不被虐到,默默的拿出小本本记录所有的问题了。
我不会告诉你写这个系列是因为昨晚接到阿里面试被虐成了渣渣然后一个人在那里尬笑了很久!!!

首先什么是跨域

浏览器有一个同源策略,为了保护用户的信息安全,你看我们Cookie不是每次都会传给后端咩,那如果其他域名下还可以访问我这个网站的Cookie,还怎么保证数据的安全咧。


那么什么情况不是同一域呢~

  • http或者https之类的协议不相同,即属于跨域。

例如:

http://www.baidu.com
https://www.baidu.com
  • 不同域名当然也属于跨域。

例如:

http://www.baidu.com
http://www.bilibili.com
  • 不同二级域名也属于跨域

例如:

http://www.baidu.com
http://hehe.baidu.com
  • 端口不一致也属于跨域

例如:

http://www.baidu.com:8080
http://www.baidu.com  /* 默认端口是80,所以咧,你80的端口可以直接输入地址的*/

那么,接下来就会问你跨域的方式有哪些。
当然有的面试官还不给人机会扯上面我刚刷上的技能点就开始问下一道问题,啊西吧。


跨域的几种方式

嘿嘿,首先列一下常用的几种。

  1. proxy代理
  2. cors
  3. JSONP
  4. xdr (这个呢,是针对ie8、9的解决方式,因为我最常写的是移动端的,所以这个也了解的不多。)

扯点闲话,我是16年年底才开始接触到跨域这种东西的,之前懵懂阶段在css和js上面撞的头破血流,当然现在这俩也没有对我有多友好,只有我待他们如同亲孙子一般的爱护。哼!
生硬的文字让人想睡觉啊…………
但是你要想你每多回答对一道题,你的工资也许就往上涨1k啊!!!
虽然以上是我的猜想,不过还是有机会的,咩哈哈哈哈哈哈哈哈……哈…哈…哈……


我们现在比喻一下。

我当前在的这个域就是一个房子,跨域就是我要去拿隔壁房子里的东西,因为同源政策,所以我不能把手伸出房子的窗户,但是我可以从窗户口去拿取或者丢出东西。

下面来详细说说这几个代理的方式哈,一般问的比较多的就是2、3了,如果对代理没兴趣直接下拉一下就看到了。


proxy代理

这个就很好理解啦,所谓的同源政策不是浏览器发出的咩。
就像我的手只能在我自己的屋子里伸,只可以通过这个窗户口出去,烟囱什么其他地方我都伸不出去。
那么我找一个站在我窗口的人,借助他的手把我的请求丢给隔壁屋子的人,然后再借用他的手把我要的东西还给我。

常用的工具有ngnix、webpack。

先说webpack吧,你看vue脚手架里面,配置代理十分的简单,只需要在config目录找到index.js,dev里添加proxyTable就好啦。

proxyTable: {

      '/api': {

            target: 'http://aa.bb.com:8989', // 你接口的域名  http://aa.bb.com:8989

            //secure: false,      // 如果是https接口,需要配置这个参数

            changeOrigin: true,     // 如果接口跨域,需要进行这个参数配置

            pathRewrite: {

              '^/api': ''//这里理解成用‘/api'代替target里面的地址,后面组件中我们掉接口时直接用api代替 
            //比如我要调用'http://aa.bb.com:8989/hahahah',直接写‘/api/hahah'即可

            }

        }

   },

然后ngnix的配置是这样的,修改nginx.conf里面的server里面的location里面的proxy_pass。
嘿嘿嘿嘿看不懂没关系,我写个例子。

server {
    listen       80;                                                         
    server_name  0.0.0.1; // 你自己页面里面写的请求地址

    #默认请求
    location / {
        proxy_pass http://aa.bb.com/; // 帮你转到你真正要请求的地址
    }
}

大致是这样的,其余的要去看文档哦,看文档的宝宝是最棒的。


cors(Cross-origin resource sharing)

哇塞这个就碉堡了,几乎所有浏览器都支持,但是ie必须10以上。
这是啥呢,其自己翻译英文去。 _

这里丢上阮大神的文章
链接描述

嗯嗯如果想详细了解的话,可以去看看。

我这里大致借用阮老师的话总结一下。

跟JSONP比较:

JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

请求方式:

要在服务器端的response header里面加一个 Access-Control-Allow-Origin: 指定域名|| ( 表示所有域名都可以跨域), 浏览器端便可以发起post的跨域请求。

说实话我对这个也不是特别的了解,所以以后了解到还是会补充哒~


JSONP

终于到你了,这个让我悲喜交加的朋友。
我之前面试也问过这个问题,我的回答大都是……

静态文件不受同源政策影响,我可以返回一个script里面有一个回调函数,函数的里面是我要的东西。

一般这么说普通面试官都能被我忽悠过去了,但是!!!!
但是总有忽悠不过去的!!!
这里还是简单介绍一下吧,原理可以简单说明,可是基础知识不能,还是要补的。
先丢上我朋友发我的一张图

clipboard.png

首先:我们从基础的说起。
我现在有两个js

a.js

var name = '啊西吧~'

b.js

console.log(name)

先运行a,再运行b,我们的name就出来了。
jsonp本身也就是这样的。

jsonp的原理就是手动创建script,然后script.src = 'b.js'。

可以简单的说,我们的步骤是这样的:
创建a.js => 请求数据、创建b.js => 运行b.js然后调用a.js

其中跨域的地方,就藏在第二点这里。

a.js

function a(data) {
    alert(`我是从${data.url}网站来的,我叫${data.name}`)
}

b.js(通过设置这个script的src

a({url: '尼叩', name: '大吉祥'})

嗯嗯结束了。
其实并没有,关于这个我查了不少资料,有的对有的错,但是至少使用上来看这么理解比较简单一点……
具体各位宝宝还是要多看看基础哒。


xdr

不得不说,这个我没用过,待朕去查询一番。

………………
………………
………………
好了我找完了。

首先打开官方文档,给他一个介绍。

通过使用 Internet Explorer 8 中的跨域请求(缩写为“XDR”),开发人员可以创建跨网站数据聚合方案。 这个名为 XDomainRequest 的请求与 XMLHttpRequest 对象类似,但编程模型更加简单,它可以提供一种最简单的方式来向支持 XDR 的第三方站点发出匿名请求,并选择使这些站点的数据可跨域使用。 只需三行代码即可生成基本的跨站点请求。 这将确保针对公共站点(例如,博客或其他社交网络应用程序)的数据聚合简单、安全和快速。

但是因为我没怎么遇到过,我相信现在也仍然有不少公司需要兼容ie低级浏览器,不过也是很大部分不需要兼容的,所以详细去看可能让你犯困~
那我来总结一下。

因为我们强大而坚挺的ie低版本浏览器并不支持cors的跨域方法,这个时候xdr就诞生了。
它实现了CORS的部分规范,只支持GET/POST形式的请求。另外在协议部分只支持http和https

在服务器端,依旧要求在响应报头添加"Access-Control-Allow-Methods"标签(这点跟CORS一致

使用方法如下:

创建一个XDomainRequest的实例,调用open()方法,再调用send()方法。但与XHR对象的open()方法不同,XDR对象的open()方法只接收两个参数:请求的类型和URL,因为所有XDR请求都是异步执行的,不能用它来创建同步请求。

请求返回之后,会触发load事件,相应的数据也会保存在responseText属性中


哎呀终于打完了,蜜汁感动。
面试嘛,其实就是掏你底细的一种办法,我还是小白一只,虽然用过三大框架,但是基础还是比较弱的,刚从爬电线杆的专业转过来,不管怎么说这一路还是有人帮忙的,非常幸福~

面试了很久,最后越来越明白,其实真的框架是工具,可以帮你很多,但是最重要的还是基础。
所以基础不好的宝宝们,我们以后一起来补呀~~~

么么哒~


darklinda588
141 声望6 粉丝