一、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/n/157675.html
微信扫一扫
支付宝扫一扫