前述:
先了解下什么是跨域,什么是同源
详解跨域请求的两种方式,支持post请求
JS AJAX跨域被阻止 CORS 头缺少 'ACCESS-CONTROL-ALLOW-ORIGIN'(只要代码的看这个,其他的偏理论)
JSONP实现跨域请求 不支持POST!
ajax请求携带cookie和自定义请求头header(跨域和同域)
目录
先了解下什么是跨域,什么是同源
一、详解跨域请求的两种方式,支持post请求
JSONP实现跨域
这个调用实际上的实现原理是
jsonp实现的缺点
服务端设置支持跨域
小结
二、JS AJAX跨域被阻止 CORS 头缺少 'ACCESS-CONTROL-ALLOW-ORIGIN'【只关注代码的看这里】
解决办法1:
解决办法2:
解决办法三:
解决办法四:
三、JSONP实现跨域请求 不支持POST!
jQuery封装JSONP
通过$.getJSON()
四、ajax请求携带cookie和自定义请求头header(跨域和同域)
ajax请求携带cookie、自定义header总结:
1. ajax跨域请求(无cookie、无header)案例(java)
2. ajax跨域请求获取和创建cookie案例(java)
3. ajax跨域请求,携带请求头header案例(java)
3. jsonp实现跨域读写cookie案例(java)
参考博客:
先了解下什么是跨域,什么是同源
一、详解跨域请求的两种方式,支持post请求
原先一直以为要实现跨域请求只能用jsonp,只能支持GET请求,后来了解到使用POST请求也可以实现跨域,但是需要在服务器增加Access-Control-Allow-Origin和Access-Control-Allow-Headers头。下面说明下两个不同的方法实现的方式和原理。
JSONP实现跨域
常用的jquery实现跨域调用
$.ajax({
url: "http://127.0.0.1/~chenjiebin/mycode/php/crossdomain/index.php",
dataType: "jsonp",
jsonp: "callback",
context: document.body,
success: function(data) {
console.log(data);
}
});
核心代码
dataType: "jsonp",
jsonp: "callback",
这个调用实际上的实现原理是
在网页中构造一个script标签,将src设置为对应的url,并增加上相应的callback参数,形如如下格式:
<script src="http://127.0.0.1/~chenjiebin/mycode/php/crossdomain/index.php?callback=jQuery211018970995225637144_1465350372062&_=1465350372063"></script>
请求的服务端代码如下:
$data = json_encode(array("id" => "1", "name" => "tom"));
$callback = $_GET["callback"];
echo $callback . "(" . $data . ")";
实际上最后返回的内容就是一段js代码:
jQuery211018970995225637144_1465350372062({"id":"1","name":"tom"})
当浏览器获取到该段js代码后就会执行这个函数,从而实现回调ajax请求时设置的success方法。
jsonp实现的缺点
了解了原理后,就知道jsonp实现的跨域方式不支持post请求,只能支持get请求。但是如果需要支持post请求该怎么办呢?下面谈下服务器端设置的方式。
服务端设置支持跨域
主要是Access-Control-Allow-Origin头参数,该参数用来指定允许哪个来源的域请求。服务端代码如下:
// 表示支持所有来源的域进行请求
// 实际在操作过程中可以设置为指定域
header('Access-Control-Allow-Origin:*');
$data = json_encode(array("id" => "1", "name" => "tom"));
echo $data;
对应的js代码:
$.ajax({
type: "POST",
url: "http://127.0.0.1/~chenjiebin/mycode/php/crossdomain/header.php",
dataType: "json",
success: function(data) {
console.log(data);
}
});
可以支持post请求。
小结
实际上个人并不是特别喜欢用跨域请求的方式,可能会带来一些不可预见的安全问题。比较习惯的方式通过本域下的服务端和跨域的源服务器进行交互。
二、JS AJAX跨域被阻止 CORS 头缺少 'ACCESS-CONTROL-ALLOW今天ajax请求域名的时候出现
已阻止跨源请求:同源策略禁止读取位于 http://www.zuimeimami.com*****的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
解决办法1:
var url='http://localhost:8080/WorkGroupManagment/open/getGroupById"
+"?id=1&callback=?';
$.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);
}});
划重点
url携带:callback=?
请求时要: dataType:'jsonp'
并且只支持: type:'get'
解决办法2:
var url="http://localhost:8080/WorkGroupManagment/open/getGroupById"
+"?id=1&callback=?";
$.jsonp({
"url": url,
"success": function(data) {
$("#current-group").text("当前工作组:"+data.result.name);
},
"error": function(d,msg) {
alert("Could not find user "+msg);
}
});
划重点
url携带:callback=?
请求时用: $.jsonp()
我没有测试过, 不知道源作者测试过没
解决办法三:
被请求页面加上下面代码,最好content填写域名
<meta http-equiv="Access-Control-Allow-Origin" content="*">
解决办法四:
在请求控制器加上
header("Access-Control-Allow-Origin: *");
三、JSONP实现跨域请求 不支持POST!
JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写。
JSONP实现跨域请求的原理简单的说,就是动态创建<script>
标签,然后利用<script>
的src 不受同源策略约束来跨域获取数据。
JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。
动态创建<script>
标签,设置其src,回调函数在src中设置:
var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1&callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
在页面中,返回的JSON作为参数传入回调函数中,我们通过回调函数来来操作数据。
function handleResponse(response){
// 对response数据进行操作代码
}
了解了JSONP的基本使用方法,我们在实现上面通过ajax调用豆瓣接口的需求,实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP实现跨域2</title>
</head>
<body>
<div id="mydiv">
<button id="btn">点击</button>
</div>
</body>
<script type="text/javascript">
function handleResponse(response){
console.log(response);
}
</script>
<script type="text/javascript">
window.onload = function() {
var oBtn = document.getElementById('btn');
oBtn.onclick = function() {
var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1&callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
};
};
</script>
</html>
在控制台,我们可以查看到返回的response数据格式为JSON对象格式的,具体需要取出哪些参数,可以根据自己的需要:
JSONP目前还是比较流行的跨域方式,虽然JSONP使用起来方便,但是也存在一些问题:
首先, JSONP 是从其他域中加载代码执行。如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时除了完全放弃 JSONP 调用之外,没有办法追究。因此在使用不是你自己运维的 Web 服务时,一定得保证它安全可靠。
其次,要确定 JSONP 请求是否失败并不容易。虽然 HTML5 给<script>
元素新增了一个 one rror事件处理程序,但目前还没有得到任何浏览器支持。为此,开发人员不得不使用计时器检测指定时间内是否接收到了响应。
jQuery封装JSONP
对于经常用jQuery的开发者来说,能注意到jQuery封装的$.ajax
中有一个dataType
属性,如果将该属性设置成dataType:"jsonp"
,就能实现JSONP跨域了。需要了解的一点是,虽然jQuery将JSONP封装在$.ajax
中,但是其本质与$.ajax
不一样。
通过jQuery的$.ajax
实现跨域的代码参考如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery实现JSONP</title>
</head>
<body>
<div id="mydiv">
<button id="btn">点击</button>
</div>
</body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script type="text/javascript">
$(function(){
$("#btn").click(function(){
$.ajax({
async : true,
url : "https://api.douban.com/v2/book/search",
type : "GET",
dataType : "jsonp", // 返回的数据类型,设置为JSONP方式
jsonp : 'callback', //指定一个查询参数名称来覆盖默认的 jsonp 回调参数名 callback
jsonpCallback: 'handleResponse', //设置回调函数名
data : {
q : "javascript",
count : 1
},
success: function(response, status, xhr){
console.log('状态为:' + status + ',状态是:' + xhr.statusText);
console.log(response);
}
});
});
});
</script>
</html>
最后的结果与JavaScript通过动态添加<script>
标签得到的结果是一样的。
通过$.getJSON()
利用getJSON来实现,只要在地址中加上callback=?参数即可,参考代码如下:
$.getJSON("https://api.douban.com/v2/book/search?q=javascript&count=1&callback=?", function(data){
console.log(data);
});
ajax请求携带cookie、自定义header总结:
错误:
1.ajax请求时是不会自动带上cookie的,要是想让他带上的话,必须设置withCredential为true。正确:
1.ajax同域请求下,ajax会自动带上同源的cookie;
2.ajax同域请求下,ajax添加自定义请求头(或原装)header,前端、后台不需要增加任何配置,
并且不会因为增加自定义请求头header,而引起预检查请求(options);
3.ajax跨域请求下,如果不需要携带cookie、请求头header,只需要在后台配置相应参数即可;
后台参数:
(1).Access-Control-Allow-Origin:设置允许跨域的配置, 响应头指定了该响应的资源是否被允许与给定的origin共享;
4.ajax跨域请求下,ajax不会自动携带同源的cookie,需要通过前端配置相应参数才可以跨域携带同源cookie,后台配置相应参数才可以跨域返回同源cookie;
前端参数:
withCredentials: true(发送Ajax时,Request header中会带上Cookie信息)
后台参数:
(1).Access-Control-Allow-Origin:设置允许跨域的配置, 响应头指定了该响应的资源是否被允许与给定的origin共享;
特别说明:配置了Access-Control-Allow-Credentials:true则不能把Access-Control-Allow-Origin设置为通配符*;
(2).Access-Control-Allow-Credentials:响应头表示是否可以将对请求的响应暴露给页面(cookie)。返回true则可以,其他值均不可以。
5.ajax请求任何时候都不会带上不同源的cookie(Cookie遵循同源策略);
6.ajax跨域请求下,ajax添加自定义或者原装的请求头,请求会发送两次,第一次预检查请求,第二次正常请求,详细描述:
post(或GET)跨域请求时,分为简单请求和复杂请求,跨域携带自定义或者原装请求头头时是复杂请求。
复杂请求会先发送一个method 为option的请求,目的是试探服务器是否接受发起的请求. 如果服务器说可以,再进行post(或GET)请求。
对于java后台web应用,跨域需要添加一个过滤器(过滤器详见下面案例代码),这个过滤器做的事就是,加了几个http header在返回中,
Access-Control-Allow-Origin 我能接受的跨域请求来源,配置主机名
Access-Control-Allow-Headers 表示能接受的http头部,别忘了加入你自己发明创造的头部
Access-Control-Allow-Methods 表示能接受的http mothed ,反正就那几种,全写上也无妨,猥琐点就只写 post, options
如果是OPTION返回空,设置返回码为202,202表示通过。
需要前端配置相应参数才可以跨域携带请求头,后台配置相应参数进行跨域携带请求头;前端参数:
crossDomain:true(发送Ajax时,Request header 中会包含跨域的额外信息,但不会含cookie(作用不明,不会影响请求头的携带))后台参数(配置预检查过滤器):
(1)Access-Control-Allow-Origin:设置允许跨域的配置, 响应头指定了该响应的资源是否被允许与给定的origin共享;
(2)Access-Control-Allow-Credentials:响应头表示是否可以将对请求的响应暴露给页面(cookie)。返回true则可以,其他值均不可以;
(3)Access-Control-Allow-Headers:用于预检请求中,列出了将会在正式请求的 Access-Control-Request-Headers 字段中出现的首部信息。(自定义请求头);
(4)Access-Control-Allow-Methods:在对预检请求的应答中明确了客户端所要访问的资源允许使用的方法或方法列表;亲测小结论:
1.ajax跨域请求下,后台不配置跨域Access-Control-Allow-Origin,同样能够执行后台方法,但是无法执行ajax的success的方法,控制台报跨域错误;
2.ajax跨域请求下,前端配置withCredentials: false,同样能够执行后台方法,但是无法携带同源cookie,后台无法获取;
3.ajax跨域请求下,前端配置withCredentials: true,后端没有配置Access-Control-Allow-Credentials:true,同样能够执行后台方法,并能够生成cookie并返回浏览器,但是无法执行ajax的success的方法,控制台报跨域错误;
4.ajax跨域请求下,前端配置withCredentials: false或不配置withCredentials,后端配置Access-Control-Allow-Credentials:true或者false,同样能够执行后台方法,并能够生成cookie并返回浏览器,但是无法携带同源cookie,能够执行ajax的success的方法;
5.Cookie携带只区分域名,不区分端口;
6.jsonp可以携带cookie,但只能携带所属域名的cookie(同源策略);
7.jsonp可以跨域生成cookie,流程如下:跨域请求之后,在服务器端生成cookie,并在浏览器端记录相应的cookie;
8.静态资源同样会携带cookie(js和图片等),但是如果是和当前页面不同域只是在network中不显示cookie选项,但是后台能够获取到对应cookie;
9.ajax同域请求会自动带上同源的cookie,不会带上不同源的cookie;
10.这是MDN对withCredentials的解释: MDN-withCredentials ,我接着解释一下同源。
众所周知,ajax请求是有同源策略的,虽然可以应用CORS等手段来实现跨域,但是这并不是说这样就是“同源”了。ajax在请求时就会因为这个同源的问题而决定是否带上cookie,这样解释应该没有问题了吧,还不知道同源策略的,应该去谷歌一下看看。总结:最好前端后台配置跨域,则同时配置相应的跨域配置,否则总会出现不可控的错误;
1. ajax跨域请求(无cookie、无header)案例(java)
(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com,java后端代码如下:
注意:Access-Control-Allow-Origin
/**
*
* @Title: getAjaxCross
* @Description: TODO(ajax请求,跨域)
* @param request
* @param response
*/
@RequestMapping(value ="/getAjaxCross",method= {RequestMethod.GET})
public void getAjaxCross(HttpServletRequest request, HttpServletResponse response){
try {
response.setCharacterEncoding("UTF-8");
//设置允许多个域名允许跨域集合
String[] allowDomains = {"http://czt.casicloud.com", "http://czt.ming.com"};
Set allowOrigins = new HashSet(Arrays.asList(allowDomains));
String origin = request.getHeader("Origin");
if(allowOrigins.contains(origin)){
//设置允许跨域的配置:Access-Control-Allow-Origin: 响应头指定了该响应的资源是否被允许与给定的origin共享
response.setHeader("Access-Control-Allow-Origin", origin);
}
//数据
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("message", "ajax请求,跨域成功");
String result = JsonUtils.objectToJson(resultMap);
response.getWriter().write(result);
} catch (Exception e) {
e.printStackTrace();
}
}
(2)前端页面代码如下:
//4.ajax跨域
function getCookieAjaxCross() {
$.ajax({
type:"get",
url:"http://czt.ming.com/xxx/xxx/xxx/getAjaxCross",
async:true,
data:{},
dataType: 'json',
success: function(data) {
console.log(data);
}
});
}
getCookieAjaxCross();
(3)测试ajax跨域请求:
通过http://czt.casicloud.com/xxx/xxx访问页面,js触发ajax跨域请求http://czt.ming.com/xxx/xxx/xxx/getAjaxCross,前端和后台如果不按照代码中配置相应参数会报各种跨域错误;
2. ajax跨域请求获取和创建cookie案例(java)
(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com,java后端代码如下:
注意:Access-Control-Allow-Credentials和Access-Control-Allow-Origin
/**
*
* @Title: getCookieAjax
* @Description: TODO(ajax请求,跨域传递cookie)
* @param request
* @param response
*/
@RequestMapping(value ="/getCookieAjax",method= {RequestMethod.GET})
public void getCookieAjax(HttpServletRequest request, HttpServletResponse response){
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Allow-Credentials", "true");
//设置允许多个域名允许跨域集合
String[] allowDomains = {"http://czt.casicloud.com", "http://czt.ming.com"};
Set allowOrigins = new HashSet(Arrays.asList(allowDomains));
String origin = request.getHeader("Origin");
if(allowOrigins.contains(origin)){
//设置允许跨域的配置:Access-Control-Allow-Origin: 响应头指定了该响应的资源是否被允许与给定的origin共享
response.setHeader("Access-Control-Allow-Origin", origin);
}
//获取cookie
Cookie[] cookies = request.getCookies();
//设置cookie
Cookie cookie = new Cookie("access_token_ajax", UUID.randomUUID().toString());
cookie.setPath("/");
response.addCookie(cookie);
//数据
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("cookies", cookies);
resultMap.put("message", "ajax请求,跨域传递cookie成功");
String result = JsonUtils.objectToJson(resultMap);
response.getWriter().write(result);
} catch (Exception e) {
e.printStackTrace();
}
}
(2)前端页面代码如下:
注意:withCredentials和crossDomain(作用不明)
//4.ajax跨域携带cookie和自定义请求头header
function getCookieAjaxCross() {
$.ajax({
type:"get",
url:"http://czt.ming.com/industry/api/publishForeign/getCookieAjax",
async:true,
data:{},
dataType: 'json',
xhrFields: {
withCredentials: true // 发送Ajax时,Request header中会带上 Cookie 信息。
},
crossDomain: true, // 发送Ajax时,Request header 中会包含跨域的额外信息,但不会含cookie(作用不明,不会影响请求头的携带)
success: function(data) {
console.log(data);
}
});
}
getCookieAjaxCross();
(3)测试ajax跨域请求获取和创建cookie:
通过http://czt.casicloud.com/xxx/xxx访问页面,js触发ajax跨域请求http://czt.ming.com/xxx/xxx/xxxx/getCookieAjax,前端和后台如果不按照代码中配置相应参数会报各种跨域错误;
3. ajax跨域请求,携带请求头header案例(java)
(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com;
(2)ajax跨域携带请求头会发送两次请求,一次预检查请求(options),预检查请求通过之后才会进行真正的请求,所以java后台需要配置相应的跨域过滤器,如下:
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @ClassName: CorsFilter
* @Description: TODO(跨域请求过滤器)
* @author clm
* @date 2019年10月25日
*
*/
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
/*
* 跨域请求头服务端配置:
* 1.Access-Control-Allow-Origin:设置允许跨域的配置, 响应头指定了该响应的资源是否被允许与给定的origin共享
* 2.Access-Control-Allow-Credentials:响应头表示是否可以将对请求的响应暴露给页面(cookie)。返回true则可以,其他值均不可以。
* 3.Access-Control-Allow-Headers:用于预检请求中,列出了将会在正式请求的 Access-Control-Request-Headers 字段中出现的首部信息。(自定义请求头)
* 4.Access-Control-Allow-Methods:在对 预检请求的应答中明确了客户端所要访问的资源允许使用的方法或方法列表。
*/
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
//设置允许多个域名允许跨域集合
String[] allowDomains = {"http://czt.casicloud.com", "http://czt.ming.com"};
Set<String> allowOrigins = new HashSet<String>(Arrays.asList(allowDomains));
String origin = httpRequest.getHeader("Origin");
if(allowOrigins.contains(origin)){
//设置允许跨域的配置:Access-Control-Allow-Origin: 响应头指定了该响应的资源是否被允许与给定的origin共享
httpResponse.setHeader("Access-Control-Allow-Origin", origin);
}
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, access-token");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET, PUT, DELETE, POST, OPTIONS");
if (httpRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
httpResponse.setStatus(202);
httpResponse.getWriter().close();
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
web.xml中配置过滤器:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>xxx.xxx.xxx.xx.xxx.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(3)java后台Controller代码:
/**
*
* @Title: getPersonHeader
* @Description: TODO(跨域获取请求头)
* @param request
* @param response
*/
@RequestMapping(value ="/getPersonHeader",method=RequestMethod.GET)
public void getPersonHeader(HttpServletRequest request, HttpServletResponse response){
try {
response.setCharacterEncoding("UTF-8");
String personHeader = request.getHeader("Access-Token");
System.err.println("获取自定义请求头(Access-Token):" + personHeader);
//数据
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("message", "跨域获取请求头成功");
resultMap.put("personHeader", personHeader);
String result = JsonUtils.objectToJson(resultMap);
response.getWriter().write(result);
} catch (Exception e) {
e.printStackTrace();
}
}
(4)前端页面代码如下:
注意:crossDomain(作用不明)
//同域前端设置自定义请求头,后端获取自定义请求头
function getPersonHeader() {
$.ajax({
type:"get",
url:"/xxx/xxx/xxx/getPersonHeader",
async:true,
//ajax配置请求头方式,第一种
headers: {
"Access-Token":"Access-Token123456",//自定义请求头
"Content-Type":"application/json;charset=utf8"
},
//ajax配置请求头方式,第二种
//beforeSend : function(request) {
// request.setRequestHeader("Access-Token", "Access-Token123456");
// request.setRequestHeader("Content-Type", "application/json;charset=utf8");
//}
data:{},
success: function(data) {
console.log(data);
}
});
}
getPersonHeader();
//跨域前端设置自定义请求头,后端获取自定义请求头
function getPersonHeaderCross() {
$.ajax({
type:"get",
url:"http://czt.ming.com/xxx/xxx/xxx/getPersonHeader",
async:true,
headers: {
"Access-Token":"Access-Token123456",//自定义请求头
"Content-Type":"application/json;charset=utf8"
},
data:{},
crossDomain: true, // 发送Ajax时,Request header 中会包含跨域的额外信息,但不会含cookie(作用不明,不会影响请求头的携带)
success: function(data) {
console.log(data);
}
});
}
getPersonHeaderCross();
(5)测试ajax跨域请求携带请求头header:
3. jsonp实现跨域读写cookie案例(java)
(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com;
(2)java后台jsonp代码:
/**
*
* @Title: setCookie
* @Description: TODO(jsonp跨域设置cookie)
* @param request
* @param response
*/
@RequestMapping(value ="/setCookie.jsonp",method=RequestMethod.GET)
public void setCookie(HttpServletRequest request, HttpServletResponse response){
try {
response.setCharacterEncoding("UTF-8");
//设置cookie
Cookie cookie = new Cookie("access_token", UUID.randomUUID().toString());
cookie.setPath("/");
response.addCookie(cookie);
//数据
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("cookie", cookie);
resultMap.put("message", "跨域设置cookie成功");
String result = JsonUtils.objectToJson(resultMap);
//前端传过来的回调函数名称
String callback = request.getParameter("callback");
//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了
result = callback + "(" + result + ")";
response.getWriter().write(result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @Title: getCookie
* @Description: TODO(jsonp跨域获取cookie)
* @param request
* @param response
*/
@RequestMapping(value ="/getCookie.jsonp",method=RequestMethod.GET)
public void getCookie(HttpServletRequest request, HttpServletResponse response){
try {
response.setCharacterEncoding("UTF-8");
//获取cookie
Cookie[] cookies = request.getCookies();
//数据
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("cookies", cookies);
resultMap.put("message", "跨域获取cookie成功");
String result = JsonUtils.objectToJson(resultMap);
//前端传过来的回调函数名称
String callback = request.getParameter("callback");
//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了
result = callback + "(" + result + ")";
response.getWriter().write(result);
} catch (Exception e) {
e.printStackTrace();
}
}
(3)前端代码:
//1.jsonp跨域设置cookie
function setCookieCrossJsonp() {
$.ajax({
type:"get",
url:"http://czt.ming.com/industry/api/publishForeign/setCookie.jsonp",
async:true,
data:{},
dataType: "jsonp", //返回类型为jsonp,实现跨域
jsonp:"callback", //jsonp和jsonpCallBack相当于在url后添加一个参数:?callback=back
jsonpCallback:"back", //设定回调函数的名字,传到后台,进行包装,不设定自动生成
success: function(data) { //成功执行处理,对应后台返回的back(data)方法
console.log(data);
}
});
}
setCookieCrossJsonp();
//2.jsonp跨域获取cookie
function getCookieCrossJsonp() {
$.ajax({
type:"get",
url:"http://czt.ming.com/industry/api/publishForeign/getCookie.jsonp",
async:true,
data:{},
dataType: "jsonp", //返回类型为jsonp,实现跨域
jsonp:"callback", //jsonp和jsonpCallBack相当于在url后添加一个参数:?callback=back
jsonpCallback:"back1", //设定回调函数的名字,传到后台,进行包装,不设定自动生成
success: function(data) { //成功执行处理,对应后台返回的back(data)方法
console.log(data);
}
});
}
getCookieCrossJsonp();
(4)测试jsonp跨域请求获取和创建cookie: