Spring boot 403 跨域问题处理

跨域问题处理

问题如下

1
2
3
OPTIONS http://192.168.10.196:8081/ims/dev/agent/1 403 
XMLHttpRequest connot load http://192.168.10.196:8081/ims/dev/agent/1. Respose to preflight request doesn't pass access control check : No 'Access-Control_Allow_origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had Http status code 403.

解决方法

加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
165
import 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>com.tyb.smartbox.ims.filter.CORSFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

调用

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/a2a183813aab49f484bc6959f3ce9d3d",
url: "http://127.0.0.1:8099/ims/dev/agent/05681ab4e4aa431aa81eaa1416f7bd5f",
type: 'PUT',

"contentType" : "application/json",

"data" : JSON.stringify({
name : "测试数据02"
}),
dataType: "JSON",
success: function (data) {
alert("success");
},
//异常处理
error: function (data) {
alert("error");
}
});
});