网站跨域解决方案

以你之姓@ 2022-04-13 14:16 366阅读 0赞

什么是跨域问题

是两个项目之间使用ajax(前端类似与后端技术httpclient)实现通讯,如果浏览器访问的域名地址与ajax访问的地址不一致的情况下,默认情况下浏览器会有安全机制,这个机制跨域问题,会无法获取到返回结果

浏览器跨域问题产生的原因

使用ajax请求调用第三方接口,如果ajax访问的接口域名或者端口号与浏览器访问的域名或者端口号不一致的情况下,就会产生跨域问题。(属于浏览器安全策略)跨域不属于前端问题

一定要域名和端口号都保持一致才能访问到

跨域时,请求可以访问到后台接口,但是获取不到数据

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjcwMTA2_size_16_color_FFFFFF_t_70 watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjcwMTA2_size_16_color_FFFFFF_t_70 1

环境搭建

新建两个项目

maven依赖

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.0.0.RELEASE</version>
  5. </parent>
  6. <dependencies>
  7. <!-- SpringBoot 对lombok 支持 -->
  8. <dependency>
  9. <groupId>org.projectlombok</groupId>
  10. <artifactId>lombok</artifactId>
  11. </dependency>
  12. <!-- SpringBoot web 核心组件 -->
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-web</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-tomcat</artifactId>
  20. </dependency>
  21. <!-- SpringBoot 外部tomcat支持 -->
  22. <dependency>
  23. <groupId>org.apache.tomcat.embed</groupId>
  24. <artifactId>tomcat-embed-jasper</artifactId>
  25. </dependency>
  26. <!-- springboot-log4j -->
  27. <dependency>
  28. <groupId>org.springframework.boot</groupId>
  29. <artifactId>spring-boot-starter-log4j</artifactId>
  30. <version>1.3.8.RELEASE</version>
  31. </dependency>
  32. <!-- springboot-aop 技术 -->
  33. <dependency>
  34. <groupId>org.springframework.boot</groupId>
  35. <artifactId>spring-boot-starter-aop</artifactId>
  36. </dependency>
  37. <dependency>
  38. <groupId>org.apache.httpcomponents</groupId>
  39. <artifactId>httpclient</artifactId>
  40. </dependency>
  41. <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
  42. <dependency>
  43. <groupId>com.alibaba</groupId>
  44. <artifactId>fastjson</artifactId>
  45. <version>1.2.47</version>
  46. </dependency>
  47. </dependencies>

项目一:itmayiedu-web-a

配置文件

  1. server:
  2. port: 9000
  3. spring:
  4. mvc:
  5. view:
  6. prefix: /WEB-INF/jsp/
  7. suffix: .jsp

后台

  1. @SpringBootApplication
  2. @Controller
  3. public class AIndexController {
  4. @RequestMapping("/getAInfo")
  5. public String getBInfo() {
  6. return "aIndex";
  7. }
  8. public static void main(String[] args) {
  9. SpringApplication.run(AIndexController.class, args);
  10. }
  11. }

页面

  1. <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
  2. <script type="text/javascript">
  3. $(document).ready(function() {
  4. $.ajax({
  5. type : "GET",
  6. async : false,
  7. url : "http://b.itmayiedu.com:9001/getBInfo",
  8. dataType : "json",
  9. success : function(data) {
  10. alert(data["respCode"]);
  11. },
  12. error : function() {
  13. alert('fail');
  14. }
  15. });
  16. });
  17. </script>

项目二:itmayiedu-web-b

配置文件

  1. server:
  2. port: 9001
  3. spring:
  4. mvc:
  5. view:
  6. prefix: /WEB-INF/jsp/
  7. suffix: .jsp

后台

  1. @SpringBootApplication
  2. @RestController
  3. public class BIndexController {
  4. @RequestMapping("/getBInfo")
  5. public Map<String, Object> getBInfo(HttpServletResponse response) {
  6. // 告诉浏览器允许跨域访问,*表示所有的域名都允许的
  7. response.setHeader("Access-Control-Allow-Origin", "*");
  8. Map<String, Object> result = new HashMap<>();
  9. System.out.println("这是B项目");
  10. result.put("respCode", "200");
  11. result.put("respMsg", "操作成功");
  12. return result;
  13. }
  14. public static void main(String[] args) {
  15. SpringApplication.run(BIndexController.class, args);
  16. }
  17. }

跨域问题解决方案

访问:http://a.itmayiedu.com:9000/getAInfo

host文件修改

127.0.0.1 a.itmayiedu.com
127.0.0.1 b.itmayiedu.com

1、使用jsonp解决跨域问题(不推荐,因为只能支持get请求,不支持post请求)

页面代码修改

后台代码修改

@RequestMapping(“/getBInfo”)
public void getBInfo(HttpServletResponse response, String jsonpCallback) throws IOException {
JSONObject jsonObject = new JSONObject();
jsonObject.put(“respCode”, “200”);
jsonObject.put(“respMsg”, “操作成功”);
PrintWriter printWriter = response.getWriter();
printWriter.write(jsonpCallback + “(“ + jsonObject.toJSONString() + “)”);
printWriter.close();
}

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjcwMTA2_size_16_color_FFFFFF_t_70 2

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjcwMTA2_size_16_color_FFFFFF_t_70 3

2、使用HttpClient进行转发(不推荐,因为使用效率非常低,会发送两次请求)

相当于发送两次请求,但是注意保证域名和端口号一致问题,

好处:安全,隐藏了真实调用地址,与Nginx反向代理非常相似

前端代码修改

后端新增

  1. @RequestMapping("/forwardB")
  2. @ResponseBody
  3. public JSONObject forwardB() \{
  4. JSONObject result = HttpClientUtils.httpGet("http://b.itmayiedu.com:9001/getBInfo");
  5. return result;
  6. \}

3、设置浏览器响应头允许跨域(可以推荐)

// 告诉浏览器允许跨域访问,*表示所有的域名都允许的,在公司正常代码放在过滤器中
response.setHeader(“Access-Control-Allow-Origin”, “*“);

4、使用Nginx搭建API接口网关(强烈推荐)因为保证域名和端口都一致,使用项目区分反向代理到真实项目地址

原理:保证域名和端口号永远是相同的,根据项目不同名称使用Nginx进行反向代理到真实服务器

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjcwMTA2_size_16_color_FFFFFF_t_70 4

host新增:

127.0.0.1 api.itmayiedu.com

nginx核心配置

  1. server \{
  2. listen 80;
  3. server\_name api.itmayiedu.com;
  4. location /a \{
  5. proxy\_pass http://a.itmayiedu.com:9000/;
  6. index index.html index.htm;
  7. \}
  8. location /b \{
  9. proxy\_pass http://a.itmayiedu.com:9001/;
  10. index index.html index.htm;
  11. \}
  12. error\_page 500 502 503 504 /50x.html;
  13. location = /50x.html \{
  14. root html;
  15. \}
  16. \}

前端代码

访问:http://api.itmayiedu.com/a/getAInfo

5、使用Zuul微服务搭建API接口网关(强烈推荐)SpringCloud

发表评论

表情:
评论列表 (有 0 条评论,366人围观)

还没有评论,来说两句吧...

相关阅读

    相关 网站解决方案

    什么是跨域问题 是两个项目之间使用ajax(前端类似与后端技术httpclient)实现通讯,如果浏览器访问的域名地址与ajax访问的地址不一致的情况下,默认情况下浏览器

    相关 解决方案汇总

    跨域解决方案汇总 同源策略 由于浏览器的同源策略,如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源,只要有一者不同,就会造成跨域 js