Spring Boot 解决方案
这货真没啥好纠结的,丢上去就完事了,如果想了解跨域的详细配置。
1 | import org.springframework.web.cors.CorsConfiguration; |
最终解决方案
加Filter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
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.HttpServletResponse;
public class CorsFilter implements Filter {
private static final boolean debug = true;
private FilterConfig filterConfig = null;
public CorsFilter() {
super();
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
if (filterConfig != null) {
if (debug) {
log("CrossFilter:Initializing filter");
}
}
}
@Override
public String toString() {
if (filterConfig == null) {
return ("CrossFilter()");
}
StringBuffer sb = new StringBuffer("CrossFilter(");
sb.append(filterConfig);
sb.append(")");
return (sb.toString());
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (debug) {
log("CrossFilter:doFilter()");
}
if(response instanceof HttpServletResponse){
HttpServletResponse alteredResponse = ((HttpServletResponse)response);
// I need to find a way to make sure this only gets called on 200-300 http responses
// TODO: see above comment
addHeadersFor200Response(alteredResponse);
}
doBeforeProcessing(request, response);
Throwable problem = null;
try {
chain.doFilter(request, response);
} catch (Throwable t) {
// If an exception is thrown somewhere down the filter chain,
// we still want to execute our after processing, and then
// rethrow the problem after that.
problem = t;
t.printStackTrace();
}
doAfterProcessing(request, response);
// If there was a problem, we want to rethrow it if it is
// a known type, otherwise log it.
if (problem != null) {
if (problem instanceof ServletException) {
throw (ServletException) problem;
}
if (problem instanceof IOException) {
throw (IOException) problem;
}
sendProcessingError(problem, response);
}
}
@Override
public void destroy() {
}
private void doBeforeProcessing(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (debug) {
log("CrossFilter:DoBeforeProcessing");
}
}
private void doAfterProcessing(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (debug) {
log("CrossFilter:DoAfterProcessing");
}
}
private void addHeadersFor200Response(HttpServletResponse response){
//TODO: externalize the Allow-Origin
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
response.addHeader("Access-Control-Max-Age", "1728000");
}
private void sendProcessingError(Throwable t, ServletResponse response) {
String stackTrace = getStackTrace(t);
if (stackTrace != null && !stackTrace.equals("")) {
try {
response.setContentType("text/html");
PrintStream ps = new PrintStream(response.getOutputStream());
PrintWriter pw = new PrintWriter(ps);
pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N
// PENDING! Localize this for next official release
pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
pw.print(stackTrace);
pw.print("</pre></body>\n</html>"); //NOI18N
pw.close();
ps.close();
response.getOutputStream().close();
} catch (Exception ex) {
}
} else {
try {
PrintStream ps = new PrintStream(response.getOutputStream());
t.printStackTrace(ps);
ps.close();
response.getOutputStream().close();
} catch (Exception ex) {
}
}
}
public static String getStackTrace(Throwable t) {
String stackTrace = null;
try {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
sw.close();
stackTrace = sw.getBuffer().toString();
} catch (Exception ex) {
}
return stackTrace;
}
public void log(String msg) {
filterConfig.getServletContext().log(msg);
}
}
在xml中配置:
1 | <filter> |
然后就是调用的ajax写法了:
1 | $(function () { |
Rest 配置
在tomcat web.xml文件中配置org.apache.catalina.servlets.DefaultServlet的
1 | <init-param> |
readonly参数默认是true,即不允许delete和put操作,所以通过XMLHttpRequest对象的put或者delete方法访问就会报告http 403错误。为REST服务起见,应该设置该属性为false。
下面是重头开始的解决过程,可以忽略。
问题要重前段时间说起,前端那边和我说,碰到跨域问题。
1 | OPTIONS http://192.168.10.196:8081/ims/dev/agent/1 403 |
因为我们是前后端分离,那边是用ajax访问调用的。于是乎我配置进行了配置,
解决方法 :
1 | 写在web.xml下。 |
这里有个坑,不知道为什么我用apache的
cors没有效果。。org.apache.catalina.filters.CorsFilter,也是醉了。
于是乎,在外面以为可以的时候,发现,ajax调用get,post是可以的,使用put,delete还是不可以,报405。
然后我百度到了个神奇的方法:
就是访问的时候,type是POST,_method标记DELETE。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21$(function () {
$.ajax({
url: "http://192.168.1.101:58080/smartbox_ims/dev/agent/2",
//url: "http://127.0.0.1:8081/ims/dev/agent/3",
type: 'POST',
data:{
_method : 'DELETE'
},
dataType: "JSON",
success: function (data) {
alert("success");
},
//异常处理
error: function (data) {
alert("error");
}
});
});
这样DELETE就可以了,原本以为这个问题解决掉了,但是~~。
当我用这个测试PUT的时候,碰到了一个415。。
1
Failed to load resource: the server responded with a status of 415 (Unsupported Media Type)
额,还是不行,我想了下,还是乖乖弄个Filter吧,百度了个手动档的过滤器~~。其实,之前在百度上有看到。
最后就使用到了,最顶上说的最终解决方案~~。