ajax的跨域解决方案(java+ajax)
简单的建立一个后台项目
新建servlet:
内容如下:
package a; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("执行了一个跨域请求");
response.setContentType("text/plain;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("success"); }
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
web.xml
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>a.TestServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/s/t</url-pattern>
</servlet-mapping>
前端代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<button onclick="goAjax()">ajax</button>
</body>
<script type="text/javascript" src="js/jquery-2.1.4.js" ></script>
<script type="text/javascript">
function goAjax(){
$.ajax({
url:"http://192.168.0.102:8080/a/s/t",
type:"get",
success:function(data){
console.log(data);
}
});
}
</script>
</html>
运行前后台项目,出现异常情况
在查看ajax的发送情况
从这里可以看到结果是正确返回的;并且后台也是正常执行了。
因此得出结论:
跨域是浏览器在aja返回结果的时候进行了拦截,先执行,后判断,不是后台不允许跨域;
客户端建立一条img标签,地址是刚才的ajax地址
<img src="http://192.168.0.102:8080/a/s/t" />
查看请求
查看请求,依然是成功的。
结论:跨域只发生在xmlHttpRequest对象上,通俗点说就是发生在ajax上。
浏览器从我们的请求路径中解析出我们的ajax请求的主机信息,得知是跨域请求,就会给请求头添加一个origin头信息。
我们可以在返回的时候添加一个响应头,来通过浏览器对跨域拦截。
1.通过修改后台代码实现跨域
添加过滤器CrossFilter.java
package a; import java.io.IOException; 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; public class CrossFilter implements Filter{
@Override
public void destroy() {} @Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain doChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse)res;
request.setCharacterEncoding("utf-8");
//response.setContentType("text/plain;charset=utf-8");
//response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8020");或者
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");//GET POST
//response.setHeader("Access-Control-Allow-Headers","content-type");
//跨域预检缓存
response.setHeader("Access-Control-Max-Age","3600");
doChain.doFilter(req,res);
} @Override
public void init(FilterConfig arg0) throws ServletException { } }
web.xml
<filter>
<filter-name>CrossFilter</filter-name>
<filter-class>a.CrossFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CrossFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
现在已经可以实现跨域请求了。
简单请求:
1.get,head,post
2.请求header里面
1)无自定义头
2)Content-Type为以下几种:text/plain,multipart/form-data,application/x-www-form-urlencoded.
非简单请求
1.put,delete方法的ajax请求
2.发送json字符串格式的ajax请求
3.带自定义头的ajax请求
ajax发送非简单请求的时候,会出现请求不通的情况
$.ajax({
url:"http://192.168.0.102:8080/a/s/t",
type:"post",
contentType:"application/json",
data:JSON.stringify({name:"gys"}),
success:function(data){
console.log(data);
}
});
结合上面的提示我们给过滤器添加一条头部信息。
重新运行,跨域问题解决,查看请求的时候发现,一个ajax请求发送了两边。
第一条是一条预检请求,这个请求是在发生非简单请求时,检查跨域请求是否能被通过。
如果每次请求都这样预检一次,会非常耗费网络资源,影响我们的请求速度。
可以在过滤器端添加一个预检缓存。
现在只有第一次请求的时候会出现预检请求,后面的就没有了。
可是我现在想要恢复预检请求,把预检代码注释了,可是还没到预检请求的缓存时间,同样没有办法查看到预检请求。
可以勾选谷歌浏览器的Disable cache
带cookie的ajax请求
jquery的ajax请求,指定带上cookie信息的参数是:xhrFields
function goAjax(){
$.ajax({
url:"http://192.168.0.102:8080/a/s/t",
type:"post",
xhrFields:{
withCredentials:true //发送ajajx请求的时候会带上cookie
},
success:function(data){
console.log(data);
}
});
}
请求结果:
这个时候的请求是不通的,根据提示我们修改后台java代码。
因为带有cookie信息后,浏览器就会对响应的请求做校验,这个时候*号就不好使了;
改成这样
再次请求;结果如下
根据提示添加响应头
再次请求,这个时候就访问通了。
根据以上的写法,只能有一个客户端可以进行跨域访问,如果127.0.0.1改成localhost访问就不通了,现在想要任何方向都能够实现跨域请求,并且带cookie.
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain doChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse)res; String origin=request.getHeader("Origin");
if(origin!=null && !"".equals(origin)){
response.setHeader("Access-Control-Allow-Origin", origin);
}
//request.setCharacterEncoding("utf-8");
//response.setContentType("text/plain;charset=utf-8");
//response.setHeader("Access-Control-Allow-Origin","http://127.0.0.1:8020");
//或者
//response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");//GET POST
response.setHeader("Access-Control-Allow-Headers","content-type");
response.setHeader("Access-Control-Allow-Credentials", "true");
//跨域预检缓存
//response.setHeader("Access-Control-Max-Age","3600");
doChain.doFilter(req,res);
}
现在在前端改成localhost访问 依然可以访问通。
nginx的转发,实现跨域(原理就是将上面过滤器中的内容配置到nginx中,并且上面的过滤器可以干掉了。)
为了便于演示,使用windows版的nginx,不用安装;nginx什么版本不重要。
在C:\Windows\System32\drivers\etc中修改hosts文件
修改配置文件 conf中的nginx.conf
在nginx.conf同级中新建vhost文件夹
添加b.com.conf文件,内容如下
server{
listen 80;
server_name b.com; location /{
proxy_pass http://localhost:8080/;
}
}
然后使用命令行测试我们的配置文件
表明测试成功。
把我们的后台项目跑起来,浏览器地址栏输入
b.com/a.如果界面是你的后台项目提供的界面,说明nginx代理成功了。
继续修改b.com.conf配置文件。
server{
listen 80;
server_name b.com; location /{
proxy_pass http://127.0.0.1:8080/; add_header Access-Control-Allow-Methods *;
add_header Access-Control-Max-Age 3600;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Headers $http_access_control_request_headers; if ($request_method = OPTIONS){
return 200;
}
}
}
测试配置文件是否通过
nginx.exe -t
重新载入nginx配置文件
nginx.exe -s reload
修改前端的ajax方法的路径
function goAjax(){
$.ajax({
url:"http://b.com/a/s/t", //"http://192.168.0.102:8080/a/s/t",
type:"post",
success:function(data){
console.log(data);
}
});
}
好,完美实现通过配置nginx添加跨域响应头。
nginx的配置反向代理,实现跨域
修改host文件
在nginx中vhost添加a.com.conf文件,内容如下:
server{
listen 80;
server_name a.com; location /{
proxy_pass http://127.0.0.1:8020/;
} location /ajaxserver{
proxy_pass http://127.0.0.1:8080/a/;
}
}
配置文件意思是这样的:
访问a.com/a/index.html时,niginx代理会跳转到前端项目127.0.0.1:8020/a/index.html
页面中的跨域请求通过访问/ajaxserver/t/s时,nginx会把请求转发到后台项目中,地址是127.0.0.1:8080/a/t/s;
检测配置文件,然后重新载入
nginx.exe -t
nginx.exe -s reload
好,跨域请求全部结束了。
慕课网笔记,老师讲的很好。
ajax的跨域解决方案(java+ajax)的更多相关文章
- AJAX POST&跨域 解决方案 - CORS
一晃又到新年了,于是开始着手好好整理下自己的文档,顺便把一些自认为有意义的放在博客上,记录成点的点滴. 跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是 ...
- AJAX POST&跨域 解决方案 - CORS(转载)
跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不可避免 ...
- (转) AJAX POST&跨域 解决方案 - CORS
跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不可避免 ...
- Ajax跨域解决方案大全
题纲 关于跨域,有N种类型,本文只专注于ajax请求跨域(,ajax跨域只是属于浏览器"同源策略"中的一部分,其它的还有Cookie跨域iframe跨域,LocalStorage跨 ...
- asp.net web api2.0 ajax跨域解决方案
asp.net web api2.0 ajax跨域解决方案 Web Api的优缺点就不说了,直接说怎么跨域,我搜了一下,主要是有两种. 一,ASP.NET Web API支持JSONP,分两种 1, ...
- day78_淘淘商城项目_11_单点登录系统实现 + 用户名回显 + ajax请求跨域问题详解_匠心笔记
课程计划 1.SSO注册功能实现 2.SSO登录功能实现 3.通过token获得用户信息 4.ajax跨域请求解决方案--jsonp 1.服务接口实现 SSO系统就是解决分布式环境下登录问题的,本 ...
- Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持
Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持 1. 设置 document.domain为一致 推荐1 2. Apache 反向代理 推荐1 ...
- 处理Ajax请求跨域问题
ajax跨域的原理 ajax出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”. CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resourc ...
- jQuery的ajax jsonp跨域请求
了解:ajax.json.jsonp.“跨域”的关系 要弄清楚以上ajax.json.jsonp概念的关系,我觉得弄清楚ajax是“干什么的”,“怎么实现的”,“有什么问题”,“如果解决存在的问题”等 ...
随机推荐
- S老师 C#编程数据结构篇 学习
直接插入排序 冒泡排序 简单选择排序 线性表: using System; using Sy ...
- php 数组排序 按照某字段
$arr=[ array( 'name'=>'小坏龙', 'age'=>28 ), array( 'name'=&g ...
- oracle单词
OEM Blackouts n. 黑朦:灯火管制(blackout的复数)Projection n. 投射:规划:突出:发射:推测premium adj. 高价的:优质的 ############## ...
- 性能测试之mysql监控、优化
我们在做性能测试的目的是什么,就是要测出一个系统的瓶颈在哪里,到底是哪里影响了我们系统的性能,找到问题,然后解决它.当然一个系统由很多东西一起组合到一起,应用程序.数据库.服务器.中中间件等等很多东西 ...
- margin重叠现象
1.上下/左右相邻的普通元素margin,不是两者相加之和,而是取最大值,这个现象叫做margin重叠. 2. 普通元素才会发生margin重叠,如果是float元素,就不会发生.margin是两者相 ...
- 使用.pth文件扩展python环境路径
使用.pth文件扩展python环境路径 有时候我们不希望把一个库放到 site-packages 下面,而是更愿意把它保留在原始的工程目录中,方便管理和维护.那么怎么能让 Python 运行环境找到 ...
- unicodedata.normalize()/使用strip()、rstrip()和lstrip()/encode和decode 笔记(具体可看 《Python Cookbook》3rd Edition 2.9~2.11)
unicodedata.normalize()清理字符串 # normalize()的第一个参数指定字符串标准化的方式,分别有NFD/NFC >>> s1 = 'Spicy Jala ...
- 【转】Linux安装HDF5及遇到的问题总结
Linux安装HDF5及遇到的问题总结 转自: http://www.linuxdiyf.com/linux/26164.html ubuntu版本:16.04.2 64位 从HDF官网(http ...
- kafka_2.11-0.10.0.1生产者producer的Java实现
转载自:http://blog.csdn.net/qq_26479655/article/details/52555283 首先导入包 将kafka目录下的libs中的jar包导入 用maven建立 ...
- IIS短文件名泄露漏洞检测
http://www.xxxx.com/*~1****/a.aspx http://www.xxxx.com/l1j1e*~1****/a.aspx If the first one return a ...