一、Ajax及跨域問題
Ajax是一種技術,通過局部刷新頁面,可以在用戶操作不刷新頁面的情況下完成交互,給用戶帶來更好的交互體驗。但是,Ajax請求和響應的數據是通過XMLHttpRequest對象進行交互,需要與伺服器進行跨域操作才能夠正常傳輸數據。跨域操作的限制是瀏覽器安全機制下的結果,也是為了保護用戶數據安全的措施。
通常情況下,Ajax跨域問題表現為請求數據失敗,控制台會報以下提示:
Access to XMLHttpRequest at 'http://someurl.com' from origin 'http://yourdomain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
這是因為伺服器未設置訪問控制策略,瀏覽器無法獲取響應。
解決辦法:
1、後端設置Access-Control-Allow-Origin響應頭
在後端響應中,設置Access-Control-Allow-Origin響應頭,允許指定的來源域訪問伺服器,例如:
response.setHeader("Access-Control-Allow-Origin", "*");
其中,*表示允許所有域名訪問,也可以指定單個域名。特別需要注意的是,如果Access-Control-Allow-Origin中指定的域名與當前訪問的域名不一致,那麼瀏覽器會阻止獲取響應數據。
2、使用JSONP方式跨域
JSONP(JSON with Padding)是一種跨域數據傳輸的技術,使用script標籤通過GET請求獲取數據,可以解決Ajax跨域問題。一般的JSON返回數據格式是:
{ "key":"value" }
而JSONP返回的數據格式是::
callback({ "key":"value" })
其中,callback是一個函數名,通過GET請求傳遞給伺服器,在返回數據的時候,伺服器會返回該函數的調用,實現跨域數據傳輸的目的。
3、使用代理伺服器
代理伺服器相當於一個中間人,請求發給它,代理伺服器再轉發給真正的伺服器。在實際使用中,前端請求不再向真正的伺服器,而是向代理伺服器發起請求,由代理伺服器轉發請求,在轉發的過程中,將Access-Control-Allow-Origin響應頭設置成自己的域名。這種方式的優勢在於可以掩蓋真正的伺服器IP地址,提高伺服器的安全性。
二、Java Spring Boot解決跨域問題
如果我們使用的是Java後端框架Spring Boot,可以使用Spring Boot提供的CorsConfiguration配置來解決跨域問題。當然,在配置之前,需要先導入Spring Boot的依賴。在pom.xml文件中添加以下代碼:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
然後,在Spring Boot的啟動類中添加以下代碼:
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }; } }
通過addMapping方法,將允許處理所有請求路徑;allowedOrigins設置允許跨域請求的域名, *表示允許所有域名訪問;allowedMethods設置允許的http請求方式;allowedHeaders設置允許的請求頭;allowCredentials設置是否允許發送Cookie;maxAge設置預檢請求的有效期。
三、Java Nginx配置
如果伺服器使用的是Nginx,可以配置Nginx來解決跨域問題。在Nginx的配置文件中添加以下代碼:
server { listen 80; server_name yourdomain.com; location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods *; add_header Access-Control-Allow-Headers *; # 如果需要支持Cookie add_header Access-Control-Allow-Credentials true; # Access-Control-Max-Age用於對響應結果進行緩存 add_header Access-Control-Max-Age 3600; proxy_pass http://yourbackend.com; # 實際後端地址 } }
其中,add_header Access-Control-Allow-Origin *表示允許所有域名訪問;add_header Access-Control-Allow-Methods *表示允許所有http請求方式;add_header Access-Control-Allow-Headers *表示允許所有請求頭;add_header Access-Control-Allow-Credentials true表示允許發送Cookie。
四、Java Tomcat配置
還有另一種方式可以解決跨域問題,就是在Tomcat的conf/server.xml文件中添加以下代碼:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context path="" docBase="xxxapp" reloadable="true"> <filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value> </init-param> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>Content-Type,accept,Origin,X-Requested-With,Access-Control-Request-Method,Access-Control-Request-Headers</param-value> </init-param> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </Context> </Host>
其中,host節點配置CORS過濾器,使其禁止對同一個源內的請求進行訪問限制時有效。filter-name和filter-class使用CorsFilter,因為它是Tomcat自帶的,無需再寫自定義實現類。以上init-param都是默認的。
總結
以上是解決Java跨域問題的幾種方法,可以根據具體情況選擇適合自己的解決方案。無論採取哪種方式,理解跨域問題的本質,正確使用跨域技術,都是解決問題的關鍵。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/157675.html