自从接触前端开发以来,跨域这个词在我们的学习和工作中被高频重复。最近在工作中遇到了跨域。相关问题,我在这里总结记录一下。关于跨域,有N种。现在只关注ajax请求跨域(ajax跨域只是浏览器“同源策略”的一部分,其他的这里不做介绍)。内容大致如下:什么是ajax跨域?如何解决ajax跨域?如何分析ajax跨域?一、Ajax跨域的原理是什么Ajax跨域Ajax请求跨域错误,主要原因是因为浏览器的“同源策略”。CORS请求原理CORS是一个W3C标准,全称是“跨源资源共享”(Cross-originresourcesharing)。它允许浏览器向跨域服务器发送XMLHttpRequest请求,从而克服AJAX只能在同源上使用的限制。目前基本上所有的浏览器都实现了CORS标准。事实上,几乎所有的浏览器ajax请求都是基于CORS机制的,但是前端开发者可能并不关心(所以其实目前CORS的解决方案主要是考虑后台如何实现的问题)。下面是一个简化的实现示意图:如何判断是否是简单请求?浏览器将CORS请求分为两类:简单请求和非简单请求。只要同时满足以下两个条件,就是一个简单的请求。l请求方式为以下三种方式之一:HEAD、GET、POSTlHTTP头信息不超过以下字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(限三种一个值application/x-www-form-urlencoded,multipart/form-data,text/plain)没有同时满足以上两个条件,是一个非简单请求。Ajax跨域性能现象一:请求的资源没有'Access-Control-Allow-Origin'头,并且响应有HTTP状态码404,造成这种情况的原因如下:lThisajaxrequestis"Notasimplerequest”,所以在请求之前会发送一个预检请求(OPTIONS)。服务器端后台接口不允许OPTIONS请求,导致找不到对应的接口地址。解决方案:后端允许选项请求。现象2:请求的资源上没有'Access-Control-Allow-Origin'头,并且响应有HTTP状态码405这种情况:l后台方法允许OPTIONS请求,但一些配置文件(如安全配置),阻塞OPTIONS请求会导致这种现象。解决方法:关闭后台相应的安全配置。现象三:请求的资源没有'Access-Control-Allow-Origin'头,状态为200这种情况:l服务端后台允许OPTIONS请求,接口也允许OPTIONS请求,但是headersmatch当出现不匹配现象时,比如originheader校验不匹配,比如缺少一些header支持(比如常见的X-Requested-Withheader),那么服务器会将response返回给前端,并且前端检测到这个之后,会触发XHR.onerror,导致前端控制台报错解决方法:在后端添加相应的header支持。现象四:header包含多个值','出现这种问题的主要原因是做跨域配置的人不理解其中的原理,导致重复配置,比如:l很常见在.net后台(一般在web.config中配置一次origin,然后在代码中手动添加origin(比如代码手动设置return*))l.net后台常用(设置origin:*在IIS和项目的webconfig中同时存在)解决方案(一一对应):建议删除代码中手动添加的*,只使用项目配置;建议删除IIS下的配置*,只使用项目配置。2.如何解决ajax跨域一般Ajax跨域的解决方法是通过JSONP或者CORS来解决,如下:(注意JSONP几乎不用了,所以这里着重讲一下CORS)CORS解决跨域问题的原理CORS的上面已经介绍过了,这里主要介绍在实际项目中如何配置后端来解决问题。下面介绍一些常见的后台解决方案:PHP后台配置:PHP后台配置几乎是所有后台中最简单的了,按照以下步骤即可:l第一步:配置Php后台允许跨域l第二步:配置Apacheweb服务器跨域(在httpd.conf中)原代码:改成如下代码:Node.js后台配置(express框架):Node.js后台比较简单,配置即可。使用express配置如下:JAVA后台配置:JAVA后台配置只需按照以下步骤:l第一步:获取依赖jar包,下载cors-filter-1.7.jar、java-property-utils-1.9。jar这两个库文件放在lib目录下。(放在对应项目的webcontent/WEB-INF/lib/下)l第二步:如果项目是用Maven构建的,请在pom.xml中添加如下依赖:(如果不是maven,请忽略)版本应该是最新的稳定版,CORS过滤器l第三步:在项目的Web.xml中添加CORS配置(App/WEB-INF/web.xml)注意:请将以上配置文件放在web.xml前面,作为第一个filter存在(可以有多个filter)lStep4:可能的安全模块配置错误(注意在一些框架中——比如公司的私有框架,是有安全模块的,有时候配置这些安全模块会影响NET后台配置:.NET后台配置可参考以下步骤:l第一步:网站配置:打开控制面板,选择管理工具,选择iis;右键点击自己打开网站所在的网站,选择浏览;打开网站所在目录,用记事本打开web.config文件,添加如下配置信息,重启网站。如果配置还是有问题,可以考虑增加更多的headers来允许,例如:第二步:其他更多的配置。如果第一步后仍然存在跨域问题,可能是:l接口中对某些请求类型有限制(如POST等),此时请解除限制l接口在IIS服务器中,您重复配置了Origin:*,请去掉l在IIS服务器中,您重复配置了Origin:*,请去掉以解决代理请求接口跨域问题注意,因为接口代理是有代价的,这只是在开发过程中进行的。与之前的方式不同,之前的CORS是由后端解决的,这主要是因为前端代理了接口,即:l前端ajax请求本地接口l本地接口收到请求后请求数据从实际界面,然后将信息返回给前端。通常,node.js可以用于代理。这里不描述如何实现代理。方法很多,也不难。它们基本上基于node.js。搜索关键字node.js和proxyrequests可以找到很多解决方案。3、如何分析ajax跨域抓包请求数据第一步当然是要知道我们的ajax请求发送接收了哪些数据。这一步做起来并不难,不需要fiddler等工具。仅基于Chrome可以在Chrome浏览器中打开对应的ajax页面,F12打开DevToolsl发送ajax请求l右键面板->NetWork->XHR,然后找到刚才的ajax请求,点击进入Example1(普通ajaxrequest)上面的请求是一个正确的请求。为了方便起见,我已经指出了每个标题字段的含义。我们可以清楚的看到接口返回的response头字段包括:所以当浏览器收到response时,判断的是正确的请求,自然不会报错,成功获取response数据。示例2(ajax请求跨域错误)在这个请求中,接口Allow没有包含OPTIONS,所以请求出现跨域。在这个请求中,Access-Control-Allow-Origin:*出现了两次,导致Thecross-domainconfigurationwasidenticalconfiguredwasnotconfiguredcorrectly,出错了。更多的跨域错误基本都是类似的,就是上面的三个东西都不满足(Headers,Allow,Origin),这里不再赘述。示例3(ajax请求不涉及跨域)并不是所有的ajax请求错误都涉及跨域,所以请不要搞混,比如下面这样:比如这个请求的跨域配置是没有问题的,它的错误只是因为请求的Accept与响应的Content-Type不匹配。基本上,这是分析ajax请求的方法。通过Chrome,可以知道发送了哪些数据,接收到了哪些数据,然后一一对比就知道是什么问题了。最后,跨域是一个老生常谈的话题。网上也有很多跨域的资料,也有很多优质的产品。喜欢文章可以加微信哦~
