JAVA WEB之跨域问题以及解决方案(上)
名词解释:
1、Content-Type:实体头部用于指示资源的MIME类型 media type 。
2、Accept :用来告知(服务器)客户端可以处理的内容类型,这种内容类型用MIME类型来表示。
3、Origin :表明预检请求或实际请求的源站。
4、X-Requested-With:用来判断一个请求是传统的HTTP请求,还是Ajax请求。Ajax的请求一般都会带上X-Requested-With头域。
5、Last-Modified:标记请求的资源在服务器端最后被修改的时间。
配置代码:
<dependency>
<groupId>com.thetransactioncompanygroupId>
<artifactId>cors-filterartifactId>
<version>2.5version>
dependency>
<filter>
<filter-name>CORSfilter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilterfilter-class>
<init-param>
<param-name>cors.allowOriginparam-name>
<param-value>*param-value>
init-param>
<init-param>
<param-name>cors.supportedMethodsparam-name>
<param-value>GET, POST, HEAD, PUT, DELETE,OPTIONSparam-value>
init-param>
<init-param>
<param-name>cors.supportedHeadersparam-name>
<param-value>Access-Control-Allow-Origin,Content-Type,X-Requested-With,
Access-Control-Request-Method,Access-Control-Request-Headers,
Accept, Origin, Last-Modifiedparam-value>
init-param>
<init-param>
<param-name>cors.exposedHeadersparam-name>
<param-value>Set-Cookieparam-value>
init-param>
<init-param>
<param-name>cors.supportsCredentialsparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>CORSfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
这种方式需要搭建一个与前端同源的后端,用于转发请求
前端调用url:http://localhost:8080/library/findBookById?bookId=1
package test;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/findBookById")
public class FindBookByIdServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
String bookId = httpServletRequest.getParameter("bookId");
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建get请求
HttpGet httpGet = new HttpGet("http://localhost:80/A/findBookById?userName="+bookId);
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
int code = httpResponse.getStatusLine().getStatusCode();
if(code == 200){
String result = EntityUtils.toString(httpResponse.getEntity());
httpServletResponse.getWriter().print(result);
}
httpResponse.close();
httpClient.close();
}
}
这里使用到的值已经在上一篇文章已经解释过了,这里就不在赘述。
<mvc:cors>
<mvc:mapping path="/**" allowed-origins="*"
allowed-methods="POST, GET, OPTIONS, DELETE, PUT"
allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
allow-credentials="true" />
mvc:cors>
当请求携带token时,跨域的解决方案于上述方式差不多,只是需要多加一个表示token的字段。注意:这个字段不一定叫做token,要看后台代码是怎么写的
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setCharacterEncoding("utf-8");
String token = request.getHeader("access_token");
}
注意上面和下面代码的区别,生成token时,写了“token”,但解析时解析的是“access_token”(这两个命名可以随意,但为了可读性,尽量写一样的)这时,请求携带的token命名为“access_token”
则解决跨域问题时,只需在表示实际请求中允许携带的首部字段中加入“access_token”即可。
例如:
resp.setHeader("access_token","Access-Control-Allow-Headers",
"X-Requested-With, Content-Type, Authorization, Accept, Origin, User-Agent, Content-Range, Content-Disposition, Content-Description");
<init-param>
<param-name>cors.supportedHeadersparam-name>
<param-value>access_token,
Access-Control-Allow-Origin,Content-Type,
X-Requested-With,Access-Control-Request-Method,
Access-Control-Request-Headers,Accept, Origin,
Last-Modifiedparam-value>
init-param>