搜索
首页后端开发php教程最全ajax跨域解决方案

最全ajax跨域解决方案

Dec 18, 2017 pm 03:32 PM
ajax解决方案

本文将和大家分享最全ajax跨域解决方案,从刚接触前端开发起,<span style="font-size: 14px;">跨域</span>这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了,16年时也整理过一篇相关文章,但是感觉还是差了点什么,于是现在重新梳理了一下。

题纲

关于跨域,有N种类型,本文只专注于<span style="font-size: 14px;">ajax请求跨域</span>(,ajax跨域只是属于浏览器"同源策略"中的一部分,其它的还有Cookie跨域iframe跨域,LocalStorage跨域等这里不做介绍),内容大概如下:

  • 什么是ajax跨域

    • 原理

    • 表现(整理了一些遇到的问题以及解决方案)

  • 如何解决ajax跨域

    • JSONP方式

    • CORS方式

    • 代理请求方式

  • 如何分析ajax跨域

    • http抓包的分析

    • 一些示例

什么是ajax跨域

ajax跨域的原理

ajax出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”,可以参考

浏览器同源政策及其规避方法(阮一峰)

CORS请求原理

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

基本上目前所有的浏览器都实现了CORS标准,其实目前几乎所有的浏览器ajax请求都是基于CORS机制的,只不过可能平时前端开发人员并不关心而已(所以说其实现在CORS解决方案主要是考虑后台该如何实现的问题)。

关于CORS,强烈推荐阅读 
跨域资源共享 CORS 详解(阮一峰)

另外,这里也整理了一个实现原理图(简化版):

最全ajax跨域解决方案

如何判断是否是简单请求?

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。只要同时满足以下两大条件,就属于简单请求。

  • 请求方法是以下三种方法之一:HEAD,GET,POST

  • HTTP的头信息不超出以下几种字段:

    • <span style="font-size: 14px;">Accept</span>

    • Accept-Language

    • Content-Language

    • Last-Event-ID

    • Content-Type(只限于三个值application/x-www-form-urlencoded、     multipart/form-data、text/plain)

凡是不同时满足上面两个条件,就属于非简单请求。

ajax跨域的表现

说实话,当初整理过一篇文章,然后作为了一个解决方案,但是后来发现仍然有很多人还是不会。无奈只能耗时又耗力的调试。然而就算是我来分析,也只会根据对应的表现来判断是否是跨域,因此这一点是很重要的。

ajax请求时,如果存在跨域现象,并且没有进行解决,会有如下表现:(注意,是ajax请求,请不要说为什么http请求可以,而ajax不行,因为ajax是伴随着跨域的,所以仅仅是http请求ok是不行的)

注意:具体的后端跨域配置请看题纲位置。

第一种现象:<span style="font-size: 14px;">No 'Access-Control-Allow-Origin' header is present on the requested resource</span>,并且<span style="font-size: 14px;">The response had HTTP status code 404</span>

最全ajax跨域解决方案

出现这种情况的原因如下:

  • 本次ajax请求是“非简单请求”,所以请求前会发送一次预检请求(OPTIONS)

  • 服务器端后台接口没有允许OPTIONS请求,导致无法找到对应接口地址

解决方案: 后端允许options请求

第二种现象:<span style="font-size: 14px;">No 'Access-Control-Allow-Origin' header is present on the requested resource</span>,并且<span style="font-size: 14px;">The response had HTTP status code 405</span>

最全ajax跨域解决方案

这种现象和第一种有区别,这种情况下,后台方法允许OPTIONS请求,但是一些配置文件中(如<span style="font-size: 14px;">安全配置</span>),阻止了OPTIONS请求,才会导致这个现象

解决方案: 后端关闭对应的安全配置

第三种现象:<span style="font-size: 14px;">No 'Access-Control-Allow-Origin' header is present on the requested resource</span>,并且<span style="font-size: 14px;">status 200</span>

最全ajax跨域解决方案

这种现象和第一种和第二种有区别,这种情况下,服务器端后台允许OPTIONS请求,并且接口也允许OPTIONS请求,但是头部匹配时出现不匹配现象

比如origin头部检查不匹配,比如少了一些头部的支持(如常见的X-Requested-With头部),然后服务端就会将response返回给前端,前端检测到这个后就触发XHR.onerror,导致前端控制台报错

解决方案: 后端增加对应的头部支持

第四种现象:<span style="font-size: 14px;">heade contains multiple values '*,*'</span>

最全ajax跨域解决方案

最全ajax跨域解决方案

表现现象是,后台响应的http头部信息有两个<span style="font-size: 14px;">Access-Control-Allow-Origin:*</span>

说实话,这种问题出现的主要原因就是进行跨域配置的人不了解原理,导致了重复配置,如:

  • 常见于.net后台(一般在web.config中配置了一次origin,然后代码中又手动添加了一次origin(比如代码手动设置了返回*))

  • 常见于.net后台(在IIS和项目的webconfig中同时设置Origin:*)

解决方案(一一对应):

  • 建议删除代码中手动添加的*,只用项目配置中的即可

  • 建议删除IIS下的配置*,只用项目配置中的即可

如何解决ajax跨域

一般ajax跨域解决就是通过JSONP解决或者CORS解决,如以下:(注意,现在已经几乎不会再使用JSONP了,所以JSONP了解下即可)

JSONP方式解决跨域问题

jsonp解决跨域问题是一个比较古老的方案(实际中不推荐使用),这里做简单介绍(实际项目中如果要使用JSONP,一般会使用JQ等对JSONP进行了封装的类库来进行ajax请求)

实现原理

JSONP之所以能够用来解决跨域方案,主要是因为

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。