处理Ajax请求跨域问题
ajax跨域的原理
ajax出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
基本上目前所有的浏览器都实现了CORS标准,其实目前几乎所有的浏览器ajax请求都是基于CORS机制。
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。只要同时满足以下两大条件,就属于简单请求。
- 请求方法是以下三种方法之一:HEAD,GET,POST
HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type(只限于三个值application/x-www-form-urlencoded、 multipart/form-data、text/plain)
凡是不同时满足上面两个条件,就属于非简单请求
跨域示例:
出现这种情况的原因如下:
- 本次ajax请求是“非简单请求”,所以请求前会发送一次预检请求(OPTIONS)
- 服务器端后台接口没有允许OPTIONS请求,导致无法找到对应接口地址
解决方案: 后端允许options请求。
如何解决ajax跨域
一般ajax跨域解决就是通过JSONP解决或者CORS解决,如以下:(注意,现在已经几乎不会再使用JSONP了,所以JSONP了解下即可)
JSONP方式解决跨域问题
jsonp解决跨域问题是一个比较古老的方案(实际中不推荐使用),这里做简单介绍(实际项目中如果要使用JSONP,一般会使用JQ等对JSONP进行了封装的类库来进行ajax请求)
实现原理
JSONP之所以能够用来解决跨域方案,主要是因为 <script> 脚本拥有跨域能力,而JSONP正是利用这一点来实现。具体原理如图
实现流程
JSONP的实现步骤大致如下(参考了来源中的文章)
客户端网页网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
} window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
} function foo(data) {
console.log('response data: ' + JSON.stringify(data));
};
请求时,接口地址是作为构建出的脚本标签的src的,这样,当脚本标签构建出来时,最终的src是接口返回的内容
- 服务端对应的接口在返回参数外面添加函数包裹层
foo({
"test": "testData"
});
- 由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。
注意,一般的JSONP接口和普通接口返回数据是有区别的,所以接口如果要做JSONO兼容,需要进行判断是否有对应callback关键字参数,如果有则是JSONP请求,返回JSONP数据,否则返回普通数据
使用注意
基于JSONP的实现原理,所以JSONP只能是“GET”请求,不能进行较为复杂的POST和其它请求,所以遇到那种情况,就得参考下面的CORS解决跨域了(所以如今它也基本被淘汰了)
CORS解决跨域问题
CORS的原理上文中已经介绍了,这里主要介绍的是,实际项目中,后端应该如何配置以解决问题(因为大量项目实践都是由后端进行解决的):
JAVA后台配置
JAVA后台配置只需要遵循如下步骤即可:
- 第一步:获取依赖jar包
下载 cors-filter-1.7.jar, java-property-utils-1.9.jar 这两个库文件放到lib目录下。(放到对应项目的webcontent/WEB-INF/lib/下)
- 第二步:如果项目用了Maven构建的,请添加如下依赖到pom.xml中:(非maven请忽视)
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>[ version ]</version>
</dependency>
其中版本应该是最新的稳定版本,CORS过滤器
- 第三步:添加CORS配置到项目的Web.xml中( App/WEB-INF/web.xml)
<!-- 跨域配置-->
<filter>
<!-- The CORS filter with parameters -->
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<!-- Note: All parameters are options, if omitted the CORS
Filter will fall back to the respective default values.
-->
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<!--这里可以添加一些自己的暴露Headers -->
<param-value>X-Test-1, X-Test-2</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- CORS Filter mapping -->
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
请注意,以上配置文件请放到web.xml的前面,作为第一个filter存在(可以有多个filter的)
- 第四步:可能的安全模块配置错误(注意,某些框架中-譬如公司私人框架,有安全模块的,有时候这些安全模块配置会影响跨域配置,这时候可以先尝试关闭它们)
转自:https://segmentfault.com/a/1190000012469713
处理Ajax请求跨域问题的更多相关文章
- day78_淘淘商城项目_11_单点登录系统实现 + 用户名回显 + ajax请求跨域问题详解_匠心笔记
课程计划 1.SSO注册功能实现 2.SSO登录功能实现 3.通过token获得用户信息 4.ajax跨域请求解决方案--jsonp 1.服务接口实现 SSO系统就是解决分布式环境下登录问题的,本 ...
- 解决ajax请求跨域
跨域大部分需要通过后台解决,引起跨域的原因: 3个问题同时满足 才可能产生跨域问题,即跨域(协议,主机名,端口号中有一个不同就产生跨域) 下面是解决方法 方法一 // ajax请求跨域 /* *解决a ...
- 解决Ajax请求跨域问题
from:https://blog.csdn.net/wang379275614/article/details/53333775 上篇文章提到,由于浏览器的同源策略,使得,AJAX请求只能发给同源的 ...
- 关于ajax请求跨域问题
jQuery中的异步请求跨域的方法: xhrFields: {withCredentials: true} 当设置为 true时,表示允许跨域: false时,表示禁止跨域
- Ajax请求跨域问题 -- 转载
几乎每种浏览器都存在默认的安全机制,都有同源策略,因为浏览器恶意的把每个外部请求的都当做是黑客攻击,相当于是对自身的保护,所以浏览器在运行脚本时会判断脚本与请求的页面是否是同一来源,这个同一来源,包括 ...
- ajax请求跨域问题
ajax跨域,这个是面试的时候常被问到,也是在做项目的时候会遇到的问题,在之前的项目中就有遇到过,这里根据经验写了三种分享下 1.使用中间层过渡的方式 简单来说就是"后台代理",把 ...
- web api 解决Ajax请求跨域问题
前端ajax请求接口时,经常出现跨域问题,当然了解决方法有很多种,比如: http://www.jb51.net/article/68424.htm 我本人恰好前后端都会一点,所以直接在接口端处理. ...
- WebApp开发:ajax请求跨域问题的解决
服务端:PHP 客户端:Andorid, HTML5, jQuery, ajax 现象:本想通过jQuery的ajax功能从服务器取回数据存到手机的缓存里,结果总是错误,后来想到可能是跨域问题,所以查 ...
- nginx配置 解决ajax请求跨域问题
文章来源:http://to-u.xyz/2016/06/30/nginx-cors/ 背景描述 最近在研究RESTful API接口设计,使用的是Nginx,要实现本地http://127.0.0. ...
随机推荐
- Linux命令笔记一
#查看文件大小[root@elegant-codes-3 py]# ls -lh total 1.1M -rw-r--r-- 1 root root 5.0K Feb 21 08:18 Crawl_W ...
- JS正则和点击劫持代码(第十二天 9.27)
JS正则 正则表达式:用单个字符串描述或者匹配符合特定语句规则的字符串一些字符序列组合在一起,可以简单也可以复杂模式的,可以去搜索,可以去替换 语法:/表达式/修饰符(可选)var para=/icq ...
- HDU - 5976 Detachment(逆元)
题意:将一个数x拆成a1+a2+a3+……,ai不等于aj,求最大的a1*a2*a3*……. 分析: 1.预处理前缀和前缀积,因为拆成1对乘积没有贡献,所以从2开始拆起. 2.找到一个id,使得2+3 ...
- 洛谷 P2543 [AHOI2004]奇怪的字符串
题目传送门 解题思路: 本题朴素求最长公共子序列即可,但是空间不够,怎么办呢? 空间不够,滚动数组来救 AC代码: #include<iostream> #include<cstdi ...
- 深入理解class
一, class和自定义类型的区别: 1,类声明不会被提升. 2,类声明的代码自动运行在严格模式. 3,类的所有方法都是不可枚举的,而自定的方法必须使用Object.defineProperty来设置 ...
- swift中使用UIColllectionView实现横向轮播的一般方法
// // HomeLiveRankCell.swift // YYSwiftProject // // Created by Domo on 2018/7/28. // Copyright ...
- Swift - UISplitViewController
https://blog.csdn.net/weixin_43704791/article/details/86424080 2019年01月13日 AppDelegate中: func applic ...
- 翻翻棋(找规律问题)(FZU Problem 2230)
题目是这样的: FZU Problem 2230 象棋翻翻棋(暗棋)中双方在4*8的格子中交战,有时候最后会只剩下帅和将.根据暗棋的规则,棋子只能上下左右移动,且相同的级别下,主动移动到地方棋子方将吃 ...
- Python String startswith() Method
一,摘自官方API https://docs.python.org/3/library/stdtypes.html#methods str.startswith(prefix[, start[, e ...
- android手机客户端测试-思考方向
来源公开课!!! 1.冒烟测试 Monkey 工具 目标:1.编写adb.exe的Monkey命令. 2.通过logcat定位问题,保证软件的健壮性. 2.安装.卸载测试 2.1 手机 ...