有关Ajax跨域请求的解决方案

前言

最近博主在赶项目进度。所以微信二次开发那边的博文一直没有更新。后续时间会慢慢记录这个学习历程的。来年公司要开发微信小程序。到时也会记录一下历程。

闲话少说,今天在工作中遇到了SpringMVC接收json形式的参数需求,就自己写了一张页面发送Ajax请求来测试。由于不想再正开发的项目中添加无用的测试。就另起了一个Web项目来做。这样就遇到了一个新的问题。Ajax如何发送跨域请求。

刚开始想的是如何从JSP页面中发送这个请求。看了度娘中的帖子以及各大论坛中的相关方案,也尝试了不少。在此,就说一下自己的历程。

AJAX垮与请求实现方案一

首先是一种从JSP访问本地Servlet,然后经Servlet发送到服务器A中的Controller方式,不过很遗憾,没有解决博主的问题。但是还是值得来说一下这个思路的 - 在虚拟机中建立了一个项目来发送ajax请求,发送到虚拟机中的一个Servlet中。该Servlet代码片段如下:

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//创建一个指向外域(服务器)的链接
		URL connect = new URL("http://192.168.1.184:9090/HanYiAPP/mine/test");
		HttpURLConnection openConnection = (HttpURLConnection) connect.openConnection();
		//服务器中设定请求方式的限制(最初是由JSP页面发起的POST请求。所以直接从请求中获取了)
		openConnection.setRequestMethod(request.getMethod());
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		//获取Ajax发来的数据
		Map<String, String[]> parameterMap = request.getParameterMap();
		Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
		Map<String,Object> map = new HashMap<String, Object>();
		for (Entry<String, String[]> entry : entrySet) {
			map.put(entry.getKey(), entry.getValue());
		}
		//转换成JSON对象
		JSONObject jsonObject = new JSONObject(map);
		//设置此URL连接可供输出
		openConnection.setDoOutput(true);
		OutputStreamWriter out = new OutputStreamWriter(openConnection.getOutputStream(),"UTF-8");  
		//输出
		out.write(jsonObject.toJSONString());
		out.flush(); 
		//以下 用于接收服务器返回 的数据
		StringBuffer data = new StringBuffer();  
		BufferedReader reader = new BufferedReader(new InputStreamReader(  
				openConnection.getInputStream(), "UTF-8")); 
		String line;              
		while ((line = reader.readLine()) != null) {          
			data.append(line);            
		} 
		System.out.println(data.toString());
	}
用这个方法博主测试了很久。终究是达不到想要的结果。这个方案的结果是页面上会提示"Access-Control-Allow-Origin"这个错误(这个是要在服务器做设置的。)但是数据能够正常发送和接收。

AJAX跨域请求解决方案二

之后楼主就在服务器上下手了。页面这边就简简单单的写了这样的一些js

var obj = {};
				obj['id']=1;
				obj['name'] = "test";
				
				$.ajax({
					//url:"http://localhost:8080/TestWebBefore/test",
					url:"http://192.168.1.184:9090/HanYiAPP/mine/test",
					type:"post",
					contentType:'application/json',
					dataType:"json",
					data:JSON.stringify(obj),
					//data:JSON.stringify($("fo").serialize()),
					success:function(data){
						console.log(data);
					},
					error:function(data){
						console.log(data);
					}
				});
之后便是在服务器这端做一系列的设置。

首先要解决的是AJAX跨域问题。当然,上面那个方案也能解决跨域问题,但是那样的话需要在客户端开发新的控制器。所以不是博主想要的结果。到此,不在提上述方案了。

度娘了一下AJAX跨域,发现还是有很多的码友在解决这样的事。在此,推荐一篇日志。是有关跨域资源共享的。各大论坛中总是粗略的说一下设置响应头就能解决,但是具体问题具体分析嘛。在SpringMVC种最有效的方式就是写一个filter来处理响应。核心代码如下:

HttpServletResponse rep = (HttpServletResponse)response;
		rep.addHeader("Access-Control-Allow-Origin", "*");
		rep.addHeader("Access-Control-Allow-Methods", "POST,GET");
		rep.addHeader("Access-Control-Allow-Credentials", "true");
		rep.addHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With");
		chain.doFilter(request, response);

为什么要推荐那一篇日志呢。因为上述方法中涉及的参数在日志中已经有了很好的解释和说明。

Access-Control-Allow-Origin这个字段是必须的。值为*代表着允许任何域访问。多个域的话可以用空格隔开(具体没有测试)

Access-Control-Allow-Methods这个字段是必须的。值为请求类型名。

Access-Control-Allow-Credentials该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,
Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以
包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏
览器发送Cookie,删除该字段即可

Access-Control-Expose-Headers该字段可选。跨域请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个
基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。
如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。

上述解释来自日志跨域资源共享

这样一来,就AJAX可以发送跨域请求了。

AJAX跨域请求解决方案三

<span style="white-space:pre">	</span>$.getJSON("http://URL?jsoncallback=?",JSON.stringify(obj),function(json){console.log(json);});
上述方式只能作用于GET请求
大概就有这样的几种方式来解决AJAX跨域问题。如果还有别的方案也可以一起交流哦
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值