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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章