JAVA WEB之跨域问题以及解决方案(下)

目录

一、产生跨域的原因

二、错误描述

三、HTTP访问控制(CORS)

四、解决方案

      1、@CrossOrigin 注解
      2、设置头部信息
      3、配置拦截器
      4、web.xml配置
      5、HttpClient 转发请求
      6、spring-context.xml配置

五、带token的跨域问题解决方案


JAVA WEB之跨域问题以及解决方案(上)

4、web.xml配置

名词解释:

1、Content-Type:实体头部用于指示资源的MIME类型 media type 。
2、Accept :用来告知(服务器)客户端可以处理的内容类型,这种内容类型用MIME类型来表示。
3、Origin :表明预检请求或实际请求的源站。
4、X-Requested-With:用来判断一个请求是传统的HTTP请求,还是Ajax请求。Ajax的请求一般都会带上X-Requested-With头域。
5、Last-Modified:标记请求的资源在服务器端最后被修改的时间。

配置代码:

  1. java-property-utils-1.9.1.jarcors-filter-2.6.jar 这两个jar包放到tomcat的lib目录下,或者直接在pom.xml中添加依赖:
<!-- https://mvnrepository.com/artifact/com.thetransactioncompany/cors-filter -->
<dependency>
    <groupId>com.thetransactioncompany</groupId>
    <artifactId>cors-filter</artifactId>
    <version>2.5</version>
</dependency>

  1. 打开tomcat的安装目录下的conf文件夹,找到web.xml文件,并将下列代码添加进去(放在文件中间四百多行的位置即可),或者直接在项目中的web.xml进行添加。
    <!-- 实现跨域   (filter配置放在其它所有filter的上面)-->
    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        <init-param>
        	<!-- 预检请求或实际请求的源站。-->
            <param-name>cors.allowOrigin</param-name>
            <param-value>*</param-value>
        </init-param>
        <init-param>
        	<!-- 支持的方法 -->
            <param-name>cors.supportedMethods</param-name>
            <param-value>GET, POST, HEAD, PUT, DELETE,OPTIONS</param-value>
        </init-param>
        <init-param>
        	<!-- 支持的头部 -->
            <param-name>cors.supportedHeaders</param-name>
            <param-value>Access-Control-Allow-Origin,Content-Type,X-Requested-With,
                Access-Control-Request-Method,Access-Control-Request-Headers,
                Accept, Origin, Last-Modified</param-value>
        </init-param>
        <init-param>
            <param-name>cors.exposedHeaders</param-name>
            <param-value>Set-Cookie</param-value>
        </init-param>
        <init-param>
        	<!-- 允许浏览器读取response的内容 -->
            <param-name>cors.supportsCredentials</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

5、HttpClient 转发请求

这种方式需要搭建一个与前端同源的后端,用于转发请求
在这里插入图片描述
前端调用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();
    }
}

6、spring-context.xml配置

这里使用到的值已经在上一篇文章已经解释过了,这里就不在赘述。

<!-- 接口跨域配置 -->
<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的字段。注意:这个字段不一定叫做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.supportedHeaders</param-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-Modified</param-value>
</init-param>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章