java跨域解决代码 java解决跨域问题注解

如何解决跨域问题

由 于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决 ajax的跨域问题。本篇将讲述一个小白从遇到跨域不知道是跨域问题,到知道是跨域问题不知道如何解决,再到解决跨域问题,最后找到两种方法解决ajax 跨域问题的全过程。

站在用户的角度思考问题,与客户深入沟通,找到眉山网站设计与眉山网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站设计、网站制作、企业官网、英文网站、手机端网站、网站推广、主机域名、网页空间、企业邮箱。业务覆盖眉山地区。

不知是跨域问题

起 因是这样的,为了复用,减少重复开发,单独开发了一个用户权限管理系统,共其他系统获取认证与授权信息,暂且称之为A系统;调用A系统以B为例。在B系统 中用ajax调用A系统系统的接口(数据格式为json),当时特别困惑,在A系统中访问相应的url可正常回返json数据,但是在B系统中使用 ajax请求同样的url则一点儿反应都没有,好像什么都没有发生一样。这样反反复复改来改去好久都没能解决,于是求救同事,提醒可能是ajax跨域问 题,于是就将这个问题当做跨域问题来解决了。

知跨域而不知如何解决

知道问题的确切原因,剩下的就是找到解决问题的方法了。google了好久,再次在同事的指点下知道jQuery的ajax有jsonp这样的属性可以用来解决跨域的问题。

找到一种解决方式

现在也知道了怎样来解决跨域问题,余下的就是实现的细节了。实现的过程中错误还是避免不了的。由于不了解json和jsonp两种格式的区别,也犯了错误,google了好久才解决。

首先来看看在页面中如何使用jQuery的ajax解决跨域问题的简单版:

复制代码

$(document).ready(function(){

var url='"

+"?id=1callback=?';

$.ajax({

url:url,

dataType:'jsonp',

processData: false,

type:'get',

success:function(data){

alert(data.name);

},

error:function(XMLHttpRequest, textStatus, errorThrown) {

alert(XMLHttpRequest.status);

alert(XMLHttpRequest.readyState);

alert(textStatus);

}});

});

复制代码

这样写是完全没有问题的,起先error的处理函数中仅仅是alert(“error”),为了进一步弄清楚是什么原因造成了错误,故将处理函数变 为上面的实现方式。最后一行alert使用为;parsererror。百思不得其解,继续google,最终还是在万能的stackoverflow找 到了答案,链接在这里。原因是jsonp的格式与json格式有着细微的差别,所以在server端的代码上稍稍有所不同。

比较一下json与jsonp格式的区别:

json格式:

{

"message":"获取成功",

"state":"1",

"result":{"name":"工作组1","id":1,"description":"11"}

}

jsonp格式:

callback({

"message":"获取成功",

"state":"1",

"result":{"name":"工作组1","id":1,"description":"11"}

})

看出来区别了吧,在url中callback传到后台的参数是神马callback就是神马,jsonp比json外面有多了一层,callback()。这样就知道怎么处理它了。于是修改后台代码。

后台java代码最终如下:

复制代码

@RequestMapping(value = "/getGroupById")

public String getGroupById(@RequestParam("id") Long id,

HttpServletRequest request, HttpServletResponse response)

throws IOException {

String callback = request.getParameter("callback");

ReturnObject result = null;

Group group = null;

try {

group = groupService.getGroupById(id);

result = new ReturnObject(group, "获取成功", Constants.RESULT_SUCCESS);

} catch (BusinessException e) {

e.printStackTrace();

result = new ReturnObject(group, "获取失败", Constants.RESULT_FAILED);

}

String json = JsonConverter.bean2Json(result);

response.setContentType("text/html");

response.setCharacterEncoding("utf-8");

PrintWriter out = response.getWriter();

out.print(callback + "(" + json + ")");

return null;

}

复制代码

注意这里需要先将查询结果转换我json格式,然后用参数callback在json外面再套一层,就变成了jsonp。指定数据类型为jsonp的ajax就可以做进一步处理了。

虽然这样解决了跨域问题,还是回顾下造成parsererror的原因。原因在于盲目的把json格式的数据当做jsonp格式的数据让ajax处理,造成了这个错误,此时server端代码是这样的:

复制代码

@RequestMapping(value = "/getGroupById")

@ResponseBody

public ReturnObject getGroupById(@RequestParam("id") Long id,

HttpServletRequest request, HttpServletResponse response){

String callback = request.getParameter("callback");

ReturnObject result = null;

Group group = null;

try {

group = groupService.getGroupById(id);

result = new ReturnObject(group, "获取成功", Constants.RESULT_SUCCESS);

} catch (BusinessException e) {

e.printStackTrace();

result = new ReturnObject(group, "获取失败", Constants.RESULT_FAILED);

}

return result;

}

复制代码

至此解决ajax跨域问题的第一种方式就告一段落。

追加一种解决方式

追求永无止境,在google的过程中,无意中发现了一个专门用来解决跨域问题的jQuery插件-jquery-jsonp。

有第一种方式的基础,使用jsonp插件也就比较简单了,server端代码无需任何改动。

来看一下如何使用jquery-jsonp插件解决跨域问题吧。

复制代码

var url=""

+"?id=1callback=?";

$.jsonp({

"url": url,

"success": function(data) {

$("#current-group").text("当前工作组:"+data.result.name);

},

"error": function(d,msg) {

alert("Could not find user "+msg);

}

});

JAVA跨域问题

跨域问题一般都在后台程序解决,将自己的程序通过配置文件或者代码将其允许跨域,

在有跨域安全的时候,所有前端post请求时,会发送一个与其请求名字一样的OPTIONS

此请求没有任何参数,此机制为post不知道是否有权限请求接口,发送了一个探知请求,探知

请求确认后,允许访问后调用正常Post接口。 不允许就会出现你现在的问题跨域异常。

萌新,java是开源的,比NET好多了,多看看底层

java为什么会有跨域问题

前言

相信大家在写前端脚本的时候经常会遇到发送数据到后台的情况,但是由于浏览器的限制,不同域名之间的数据是不能互相访问的,那前端怎么和后端如何进行数据之间的交换呢?

JavaScript由于安全性方面的考虑,不允许页面跨域调用其他页面的对象,那么问题来了,什么是跨域问题?

答:这是由于浏览器同源策略的限制,现在所有支持JavaScript的浏览器都使用了这个策略。那么什么是同源呢?所谓的同源是指三个方面“相同”:

域名相同

协议相同

端口相同

下面就举几个例子来帮助更好的理解同源策略。

URL

说明

是否允许通信

同一域名    允许  

不同域名    不允许  

同一域名不同端口    不允许  

同一域名不同协议    不允许  

在JAVA中处理跨域问题,通常有以下两种常用的解决方法。

第一种解决方法

后台代码在被请求的Servlet中添加Header设置:

response.setHeader("Access-Control-Allow-Origin", "*");

PrintWriter out =null;

try

{

out = response.getWriter();

} catch (IOException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

out.print("{'status':'ok'}");

out.flush();

out.close();

Access-Control-Allow-Origin这个Header在W3C标准里用来检查该跨域请求是否可以被通过,如果值为*则表明当前页面可以跨域访问。默认的情况下是不允许的。

在前端JS中需要向Servlet发出请求,请求代码如下所示:

$.ajax({

url: "your url",

type:"get or post",

dataType:"json",

data:{

....

},

success:function(data){

...

}

第二种解决方法

通过jsonp跨域请求的方式。JSONP和JSON虽然只有一个字母的区别,但是他们完全就是两回事,很多人很容易把他们搞混。JSON是一种数据交换的格式,而JSONP则是一种非官方跨域数据交互协议。

首先来说一下前端JS是怎么发送请求。代码如下所示:

$.ajax({

url:"your url",

type:"get or post",

async:false,

dataType : "jsonp",

//服务端用于接收callback调用的function名的参数

jsonp:"callbackparam",

//callback的function名称

jsonpCallback:"success_jsonpCallback",

success:function(data){

console.log(data);

},

error:function(data){

console.log(data);

}

});

这里的callbackparam和success_jsonpCallback可以理解为发送的data数据的键值对,可以自定义,但是callbackparam需要和后台约定好参数名称,因为后台需要获取到这个参数里面的值(即success_jsonpCallback)。

下面,最重要的来了,后台怎么样获取和返回数据呢。代码如下所示:

PrintWriter out =null;

String callback=req.getParameter("callbackparam");

String json=callback+"({'status':'ok'})";

try

{

out = resp.getWriter();

} catch (IOException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

out.print(json);

out.flush();

out.close();

首先需要获取参数名为callbackparam的值,这里获取到的值就是“success_jsonpCallback”。然后将这个值加上一对小括号。小括号里放入你需要返回的数据内容,比如这里我返回一个JSON对象。当然你也可以返回其他对象,比如只返回一个字符串类型数据也可以。最后前端JS返回的数据就是这样的:

success_jsonpCallback({'status':'ok'})

浏览器会自动解析为json对象,这时候你只需要在success回调函数中直接用data.status就可以了。

Spring MVC 的跨域解决方案

一句话:同一个ip、同一个网络协议、同一个端口,三者都满足就是同一个域,否则就是跨域。

基于两个方面:

a. web应用本身是部署在不同的服务器上

b.基于开发的角度 --- 前后端分离

web应用本身是部署在不同的服务器上,对应的域名也就有所不同

比如百度。

主域名:

二级域名:, ,

需要在不同的域之间,通过ajax方式互相请求,是非常常见的需求。

Spring 4中增加了对jsonp的原生支持,只需要ControllerAdvice就可以开启,方法如下:

首先新建一个Advice类,我们叫做“JsonpAdvice”,然后在里面定义接收jsonp请求的参数key:

@ControllerAdvice("cn.isy.web.sso.web")指定作用的包名

supper("callback")指定的是url中callback:

注意:

我们还可以重写AbstractJsonpResponseBodyAdvice中的feforeBodyWriteInternal方法:

做到实现url携带callback就返回jsonp格式,没有就返回正常格式

img

controller中

controller中的代码正常编写就OK,不用修改任何东西。

只要保证在cn.isy.web.sso.web包下即可!

jquery ajax

注意:必须使用jsonp的方式提交请求!

有关cors的介绍可以去详细看一下,这里就不作重复了:

CORS详解

跨资源共享CORS详解

主要配置

使用注解CrossOrigin

在controller类上添加CrossOrigin注解表示当前类中的所有入口函数都

可以实现跨域。也可以指定某个conroller中具体的方法。

img

了解一下这个注解的内容:

img

jquery ajax的写法

注意:这里不用使用jsonp的方式请求普通的ajax即可!,因为浏览器自己可以去做!

CORS全局配置

自己试了试没有成功!

资料

解释cors的原理不错

让自己变得更优秀才可以有更多资源

搜索微信号(ID:芋道源码),可以获得各种 Java 源码解析。

并且,回复【书籍】后,可以领取笔者推荐的各种 Java 从入门到架构的书籍。


网站标题:java跨域解决代码 java解决跨域问题注解
路径分享:http://ybzwz.com/article/dophshh.html