一、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-hant/n/157675.html
微信掃一掃
支付寶掃一掃