cors
和jsonp
都是用于解决跨域问题,当两个页面的协议、域名、端口号中有一个不一致时就存在了跨域,一旦出现跨域,浏览器发送跨域请求后,请求回来的数据都会被浏览器所拦截。
注意:浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到。
如何实现跨域数据请求?
现下实现跨域数据请求,最主要的两种解决方案分别是 JSONP
和 CORS
。
JSONP
: 出现的早,兼容性好(兼容低版本 IE )。是前端程序员为了解决跨域问题,被迫想出来的一种 临时解决方案,最主要的缺点 是只支持 GET
请求,不支持 POST
请求。CORS
: 出现的较晚,它是 W3C
标准,属于跨域 Ajax
请求的根本解决方案。支持 GET
和 POST
请 求。缺点 是不兼容某些低版本的浏览器。JSONP
简介JSONP
JSONP
(JSON with Padding
) 是 JSON
的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。
JSONP
的实现原理概念:浏览器端通过 标签的
src
属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做 JSONP
JSONP
不属于真正的 Ajax
请求,因为它没有使用 XMLHttpRequest
这个对象
JSONP
仅支持 GET 请求,不支持 POST、PUT、DELETE 等请求
JSONP
跨域jsonp
就是能够跨域请求数据。
利用 src
可以跨域加载 js
代码。这样就可以取到js
的代码,然后,在前端执行js
代码即可。
在后端我们只要动态生成js
代码就好了。
利用script标签,加载动态生成的js代码,js会回调相应方法,并且将数据传递给回调方法。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>jsonp实现案例title>
<script type="text/javascript">
var flightHandler = function(data){
alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
};
// 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
var url = "http://ip/WxServlet/jsonp2.js?callback=flightHandler";
// 创建script标签,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
script>
head>
<body>
body>
html>
动态生成js代码,代码里放置一个回调方法。
String code = req.getParameter("code");
String collback = req.getParameter("callback");
System.out.println(code+collback);
String str = "flightHandler({\"code\": \"CA1998\",\"price\": 1780,\"tickets\": 5});";
resp.getWriter().append(str);
接下来看下使用jquery的jsonp来实现跨域访问,例子如下:
$(function(){
$.ajax({
type: "get",
async: false,
url: "http://ip/WxServlet/jsonp2.js",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback:"flightHandler",
success: function(json){
alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
},
error: function(){
alert('fail');
}
});
});
动态生成js代码,代码里放置一个回调方法。
String code = req.getParameter("code");
String collback = req.getParameter("callback");
System.out.println(code+collback);
String str = "flightHandler({\"code\": \"CA1998\",\"price\": 1780,\"tickets\": 5});";
resp.getWriter().append(str);
CORS
简介CORS
CORS
(跨域资源共享) 由一系列 HTTP 响应头组成,这些 HTTP 响应头决定浏览器 是否阻止前端 JS
代码跨域获取资源CORS
相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制CORS
概念CORS
(Cross-Origin Resource Sharing
跨源资源共享)
当一个请求url的协议
、域名
、端口
三者之间任意一与当前页面地址不同即为跨域。
在日常的项目开发时会不可避免的需要进行跨域操作,而在实际进行跨域请求时,经常会遇到类似 No 'Access-Control-Allow-Origin' header is present on the requested resource.
这样的报错。这样的错误,一般是由于CORS
跨域验证机制设置不正确导致的。
CORS
案例import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CORSFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
//*表示允许所有域名跨域
httpResponse.addHeader("Access-Control-Allow-Origin", "*");
httpResponse.addHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept");
//允许跨域的Http方法
httpResponse.addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
}
}
<filter>
<filter-name>CorsFilterfilter-name>
<filter-class>org.du.personalsitemock.mockutil.CORSFilterfilter-class>
filter>
<filter-mapping>
<filter-name>CorsFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
$.ajax({
url: 'http://xxxx/test/cors?name=tom',
type: 'post',
data: '',
// 默认情况下,标准的跨域请求是不会发送cookie的
xhrFields: {
withCredentials: true
},
success: function(rs) {
}
})
在类或方法上添加注解即可,@CrossOrigin(origins = "*", allowCredentials = "true")
。
@RestController
@CrossOrigin(origins = "*", allowCredentials = "true")
public class TestController {
@RequestMapping(value = "test/cors")
public Object cors() {
try {
Map<String, Object> map = getParameterMap();
System.out.println(map.toString());
return output(map);
} catch (Exception e) {
e.printStackTrace();
return output("9999", "错误", e.getMessage());
}
}
}
$.ajax({
url: 'http://xxxx/test/cors?name=tom',
type: 'post',
data: '',
// 默认情况下,标准的跨域请求是不会发送cookie的
xhrFields: {
withCredentials: true
},
success: function(rs) {
}
})
CrossOrigin注解没有生效,解决方案集合
https://blog.csdn.net/suxiexingchen/article/details/104861803
CrossOrigin注解没有生效,解决方案集合
https://suxiexingchen.github.io/2020/03/14/36/
ajax携带cookie的两种方式
https://www.cnblogs.com/lgl1209/p/11527080.html
CORS和JSONP的区别,如何解决跨域问题?
https://blog.csdn.net/SunFlower914/article/details/120691847