跨域原理及常见解决办法

作为一个前端开发者,在工作中总是避免不了要涉及跨域问题,今天我们就来谈谈跨域。

什么是跨域?

浏览器从一个域名请求另一个域名的资源时,只要 协议、域名、端口 任何一处不同,便是跨域。

跨域产生的原因

跨域的产生和服务器代码什么的是无关的,它是由浏览器的同源策略导致的。
同源策略:
它是浏览器的一个安全策略,所有支持javascript的浏览器都遵循这个策略。为了用户安全着想,浏览器不允许不同协议、域名(包括子域名)、端口的地址之间进行访问。

解决跨域的方法

在实际开发中,我们避免不了要和非同源的服务器进行通讯,所以需要解决浏览器的非同源限制。从同源策略出发,要想解决跨域我们可以有以下几个方案。>

一:在浏览器设置禁止检查
通过设置--disable-web-security命令。
步骤:

①:下载并安装好chorme浏览器后在桌面找到浏览器快捷图标并点击鼠标右键的属性一栏。
②:在属性页面中的 目标 输入框里追加上 --disable-web-security 。
③:点击应用和确定后关闭属性页面,并打开chrome浏览器。如果浏览器出现提示“你使用的是不受支持的命令标记 --disable-web-security”,那么说明配置成功
注49版本后浏览器需另外设置,请自行百度。

  • 此方法因为涉及到涉及操客户端作浏览器,在实际项目中肯定是不可行的我们不能去设置每个用户的浏览器,不过在日常开发中倒可以进行测试使用。

二:使用jsonp进行跨域请求
我们都知道直接在js中直接发起ajax跨域请求是不可能的,但是我们可以引入不同域下的js资源。jsonp就是利用了这一特点,通过动态的在页面建立script标签来实现跨域请求。(通过打算点方式可以看到在head中动态添加了一个script链接,src地址即所请求资源地址阿)
`

//创建标签(createElement)
var script = document.createElement("script");
//添加地址
script.src='http://test.adress.com?callback=callBackFun';
//添加给body的(成为body包涵的孩子)
document.head.appendChild(script);

//获取返回结果的回到函数
function callBackFun(res){
    //res即获取的回调信息
    console.log(JSON.stringify(res))
}
$.ajax({
    url:'请求地址...',
    type: 'GET',
    dataType: 'jsonp',
    //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
    jsonp: 'callback',
    //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名.
    jsonpCallback: 'list',回掉函数名,默认jquery自动生成,指定jsonpCallback时可以将回掉函数写在ajax外面做其他操作,不指定时不能这样做,只能在success里做操作
    success:function(json){

    },
    error:functon(res){

    }
})

<!-- 当然的仅仅前台的这些代码是实现不了整个jsonp的跨域请求的,必须还要服务端进行修改,其中callback即是前后端约定的处理函数,此函数名必须和服务端方法名保持一致。 -->

`


  • jsonp总结:
    优点:不像ajax会受到浏览器的同源策略限制可以实现跨域,而且可以兼容非常古老的浏览器.
    缺点:只支持get请求,不支持post、put、OPTIONS等其他http请求。

CORS实现跨域

CORS(Cross-Origin Resource Sharing)跨域资源共享,是一种机制,它使用额外的http请求头来让浏览器和服务器达成特殊约定,从而告诉浏览器哪些非同源服务器上的资源可以进行访问。另外CORS机制中对复杂请求会首先发起一个预请求,来确认服务端是否允许跨域。当服务端确认允许后,客户端才会发起一个实际真是的http请求,在预请求中,服务端也可以告诉客户端是否需要携带某身份验证。

CORS分为简单请求和非简单请求:
简单请求:
①:请求方式为get、post、head.
②:Content-Type仅为text/plain、multipart/form-data、application/x-www-form-urlencoded其中一种

  • 对于简单请求,浏览器会直接发送CORS请求,在请求头里加入origin字段,在响应头里,会返回服务器设置的相关CORS字段,Access-Control-Allow-Origin字段对应的为允许跨域请求的源。若请求头里的源与服务器端设置源一致,服务器端检测通过,则允许跨域通讯。(在跨域的请求头报文里我们会看到多一个origin请求头)*

非简单请求:
①:使用了 put、delete、options、putch、trace、connect其中任一种http请求。
②:Content-Type不属于text/plain、multipart/form-data、application/x-www-form-urlencoded、中的任一种。
只要满足上面任一点即为非简单请求。

当发生非简单请求时,浏览器会首先发起一个预请求(options),来确认服务端是都允许该源进行跨域,当得到服务端确认允许后,客户端会发起一个真正的http请求,在预请求中,服务端也可以设置告诉客户端是否需要携带某种身份验证。
预检成功后,服务端响应的报文中将会展示支持的请求类型、支持的自定义首部及支持的跨域的源。
如图所示


其中
Access-Control-Allow-Origin: http://localhost:2015 允许跨域请求的源
Access-Control-Allow-Methods: post、get、delete、options 服务端支持的请求方式,注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求
Access-Control-Allow-Headers: x-request-with (服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段,多个用,分割)
Access-Control-Max-Ages: 3600 (预检请求可以被缓存的时间,单位秒,Firefox中最大24小时,Chromium中10分钟,-1表示禁止缓存,即每一次请求都要发送预请求)

一旦浏览器通过了预检请求,以后每次浏览器正常的CORS请求和简单请求一样,会有一个origin头部信息字段,响应报文里也有一个Access-Control-Allow-Origin响应头信息字段。
使用CORS实现跨域,主要需要服务端进行配置,前端无需做大修改(或者前端可以通过nginx、apach进行代理配置),不过如果携带cookie信息时,前端需要配置withCredentials为ture.此时服务端Access-Control-Allow-Origin也不能简单的设置为“*”,而是要设置成具体的请求源地址。需要进行动态配置。

CORS总结:
优点:配置方便,便于操作、可以实现任何类型的http请求。
缺点:不兼容低版本浏览器。

总结

总体来说,在实际开发中,我们都会用jsonp和CORS进行跨域请求,两者各有优劣,根据需求大家合理利用,另外在本文中如有不恰当之处,欢迎纠正!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354