文档章节

AJAX跨域总结

炁元
 炁元
发布于 2016/08/20 16:37
字数 960
阅读 265
收藏 7

       蚂蚁金服的实习即将结束,将知识总结一下。

       我们这个项目前端使用antD,antD是采用React封装的一套组件库,目前开源http://ant.design/,所有组件都是拿来即用,大大缩短了开发周期,强烈推荐。React是单页面应用,通过ajax与后台通信,而antD调试部署在8000端口,后台又是运行在另一个端口,前后台通信跨域。AJAX跨域一般有两种解决方法:CORS(跨域资源共享)和JSONP。

       先来看看JSONP,本质原理利用script标签src属性可以跨域的特性,我们自己也可以去实现JSONP,动态添加删除script标签:

function loadJs() {
  var script = document.createElement("script");
  script.src = "http://xxxxxx/get/req";
  document.body.appendChild(script);
    
  script.onload = function() {
    callback(); 
    document.body.removeChild(script);
  }
} 

       在AJAX中使用JSOP:

$.ajax({
   url: 'http://xxxxxx/get/req', 
   cache: false,
   type: 'post',
   jsonp:'callback',
   dataType:'jsonp', 
   success: function (result) {
      //处理结果的过程
   },
   error: function (XMLHttpRequest) {
      //出错回调处理
   }
});

       相应的后台代码:

     /**
	 * 测试
	 * 
	 * @throws IOException
	 */
	@RequestMapping("/get/req")
	@ResponseBody
	public void getData(HttpServletRequest req, HttpServletResponse rep) throws IOException {
		Map<String, Object> result = null;
		result = manager.getDatas();
		String callback = req.getParameter("callback");
		String json = JSONObject.toJSONString(result);
		rep.setContentType("text/javascript");
		rep.setCharacterEncoding("utf-8");
		PrintWriter out = rep.getWriter();
		out.print(callback + "(" + json + ")");
	}

       CORS分为简单请求和非简单请求,非简单请求的请求方法不是POST、GET、HEAD,或者header中包含一些特殊请求头,以及Content-Type不是application/x-www-form-urlencoded、multipart/form-data、text/plain的请求。向后台发送请求时会多发送一次option请求,并且不能携带cookie,这个后面再说。CORS只需服务器端在每次响应中设置一些响应头即可,将这些操作放在Filter中实现低耦合:

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse rep = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest) request;
        rep.addHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
        rep.setHeader("Access-Control-Allow-Credentials", "true");//跨域携带cookie
        rep.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");//非简单请求
        rep.setContentType("application/json; charset=utf-8");
        rep.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE");//非简单请求
        chain.doFilter(request, rep);
    }

       我们的项目需要接入统一登录中心,SSO大家也知道,每次请求来了之后SSOClient判断是否携带token,过期或者没有token会重定向到登录页面让用户进行登录。这里出现了一个问题,前端向后台发送AJAX请求,在用户没有登录时并不能正常重定向到登录中心,而是出现前台到登录中心页面的XMLHttpRequest跨域错误提示。但是通过浏览器直接输入后台请求URL地址,在用户没有登录时,会重定向到登录中心页面。对于这个问题的产生一开始没有头绪,进行了多种尝试之后定位到了原因。

       这里涉及到浏览器是如何处理AJAX请求重定向,当服务器将302响应发给浏览器,浏览器并不是直接进行AJAX回调处理,而是先执行302重定向,从Response Headers中读取Location信息,然后向Location中的Url发出请求,在收到这个请求的响应后才会进行AJAX回调处理。antD是个单页面应用,前后台交互通过AJAX的方式,所以当SSOFilter拦截ajax请求之后,浏览器会首先重定向到登陆中心,产生了前台到登录中心的跨域AJAX请求,当浏览器发现响应头信息没有包含Access-Control-Allow-Origin字段,从而抛出XMLHttpRequest cannot load的错误。

       CORS请求默认不发送Cookie和http认证信息,如果要把Cookie发送到服务器,一方面需要服务器同意,指定Access-Control-Allow-Credentials响应头,另一方面必须在AJAX中打开withCredentials属性,$.ajaxSetup方法设置AJAX请求的默认参数选项,多个AJAX请求时,不用为每一个请求配置请求的参数:

 $.ajaxSetup({
   xhrFields: {
     withCredentials: true
   },
 })

 

© 著作权归作者所有

炁元
粉丝 1
博文 9
码字总数 13524
作品 0
西安
程序员
私信 提问
web跨域解决方案

阅读目录 什么是跨域 常用的几种跨域处理方法: 跨域的原理解析及实现方法 总结 摘要:跨域问题,无论是面试还是平时的工作中,都会遇到,本文总结处理跨域问题的几种方法以及其原理,也让自...

幕三少
2016/09/01
0
0
ajax跨域调用webservice

最近ajax访问webservice遇到跨域的问题,网上搜索资料,总结如下(很多都是觉得人家总结不错的复制下来) <<用JSON来传数据,靠JSONP来跨域>> 先上我的已实现代码: 前端代码: $.ajax({ type:...

宿命panthers
2016/05/09
158
0
ajax跨域方法

三种方案:代理、JSONP、XHR2(XMLHttpRequest Level 2)。 第一种方法:代理 这种方式是通过后台(ASP、PHP、JAVA、ASP.NET)获取其他域名下的内容,然后再把获得内容返回到前端,这样因为在同...

Weltch
2016/12/26
19
0
JAVA用CORS实现跨域请求

之前在开发实验室的一个云服务,主要后端是使用java基于jfinal框架。我们在开发中遇到了一个小小的问题,由于我们开发通常是将前后端分离利用AJAX进行交互的。但是AJAX是不允许跨域的哦,那么...

tbaby
2015/09/05
15.5K
3
浅析Ajax跨域原理及JQuery中的实现分析

  AJAX 的出现使得网页可以通过在后台与服务器进行少量数据交换,实现网页的局部刷新。但是出于安全的考虑,ajax不允许跨域通信。如果尝试从不同的域请求数据,就会出现错误。如果能控制数...

雲霏霏
2014/12/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 年迈渔夫遭黑帮袭抢

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享Elvis Presley的单曲《White Christmas》: 《White Christmas》- Elvis Presley 手机党少年们想听歌,请使劲...

小小编辑
今天
1K
18
CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
12
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部