跨域问题解决方案

男娘i 2022-01-28 12:45 493阅读 0赞

跨域问题解决方案

五种网站跨域解决方案

  1. 使用jsonp解决网站跨域 只能支持get 不支持post

    2.使用HttpClient内部转发 效率低 发送两次请求
    3.使用设置响应头允许跨域
    4.基于Nginx搭建企业级API接口网关 保证域名和端口一直 以项目区分反向代理到真实服务器地址
    5.使用Zuul搭建微服务API接口网关

使用设置响应头允许跨域:

在B项目中添加:

response.setHeader(“Access-Control-Allow-Origin”, “*“);

  1. package com.toov5.controller;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import javax.servlet.http.HttpServletResponse;
  5. import org.springframework.boot.SpringApplication;
  6. import org.springframework.boot.autoconfigure.SpringBootApplication;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. @RestController
  10. @SpringBootApplication
  11. public class BIndexController {
  12. @RequestMapping("/getBInfo")
  13. public Map<String, Object> getBInfo(HttpServletResponse response){
  14. //告诉浏览器 允许跨域 这段代码应该放在过滤器里面的
  15. response.setHeader("Access-Control-Allow-Origin", "*"); //*代表所有 可以a.toov5.com专门的
  16. //提供给Ajax嗲用
  17. Map<String,Object> result = new HashMap<String, Object>();
  18. result.put("code", 200);
  19. result.put("msg", "登录成功");
  20. return result;
  21. }
  22. public static void main(String[] args) {
  23. SpringApplication.run(BIndexController.class, args);
  24. }
  25. }

1179709-20181121162146395-1607862452.png

JSONP解决方案:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. <script type="text/javascript"
  9. src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
  10. <script type="text/javascript">
  11. $(document).ready(function() {
  12. $.ajax({
  13. type : "POST",
  14. async : false,
  15. url : "http://b.toov5.com:8081/getBInfo",
  16. dataType : "jsonp",
  17. jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数
  18. success : function(data) {
  19. alert(data["code"]); //获取到code
  20. },
  21. error : function() {
  22. alert('fail');
  23. }
  24. });
  25. });
  26. </script>
  27. </head>
  28. <body>我是A项目 正在调用B项目
  29. </body>
  30. </html>

  

  首先该成JSONP的 形式

  1. dataType : "jsonp",
  2. jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数

访问: (生成的随机数)

1179709-20181121163750232-1396425744.png

1179709-20181121163822226-493801735.png

1179709-20181121163853272-414599488.png

注意 不支持post请求!

HttpClient方案转发:

相当于发送两次请求

隐藏了真实地址 Nginx反向代理类似

同时需要@ResponseBody哦 因为返回json格式

修改前段访问的接口 保持一致:

1179709-20181121175845287-2055574803.png

  1. $(document).ready(function() {
  2. $.ajax({
  3. type : "POST",
  4. async : false,
  5. url : "http://a.toov5.com:8080/forwardB",
  6. dataType : "json",
  7. success : function(data) {
  8. alert(data["code"]); //获取到code
  9. },
  10. error : function() {
  11. alert('fail');
  12. }
  13. });
  14. });
  15. url : "http://a.toov5.com:8080/forwardB",
  16. dataType : "json",
  17. success : function(data) {
  18. alert(data["code"]); //获取到code
  19. },
  20. error : function() {
  21. alert('fail');
  22. }
  23. });
  24. });

  

HttpClient:

  1. package com.toov5.controller;
  2. import java.io.IOException;
  3. import org.apache.http.HttpEntity;
  4. import org.apache.http.HttpStatus;
  5. import org.apache.http.client.config.RequestConfig;
  6. import org.apache.http.client.methods.CloseableHttpResponse;
  7. import org.apache.http.client.methods.HttpGet;
  8. import org.apache.http.client.methods.HttpPost;
  9. import org.apache.http.entity.StringEntity;
  10. import org.apache.http.impl.client.CloseableHttpClient;
  11. import org.apache.http.impl.client.HttpClients;
  12. import org.apache.http.util.EntityUtils;
  13. import org.slf4j.Logger;
  14. import org.slf4j.LoggerFactory;
  15. import com.alibaba.fastjson.JSONObject;
  16. public class HttpClientUtils {
  17. private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录
  18. private static RequestConfig requestConfig = null;
  19. static {
  20. // 设置请求和传输超时时间
  21. requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
  22. }
  23. /**
  24. * post请求传输json参数
  25. *
  26. * @param url
  27. * url地址
  28. * @param json
  29. * 参数
  30. * @return
  31. */
  32. public static JSONObject httpPost(String url, JSONObject jsonParam) {
  33. // post请求返回结果
  34. CloseableHttpClient httpClient = HttpClients.createDefault();
  35. JSONObject jsonResult = null;
  36. HttpPost httpPost = new HttpPost(url);
  37. // 设置请求和传输超时时间
  38. httpPost.setConfig(requestConfig);
  39. try {
  40. if (null != jsonParam) {
  41. // 解决中文乱码问题
  42. StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
  43. entity.setContentEncoding("UTF-8");
  44. entity.setContentType("application/json");
  45. httpPost.setEntity(entity);
  46. }
  47. CloseableHttpResponse result = httpClient.execute(httpPost);
  48. // 请求发送成功,并得到响应
  49. if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  50. String str = "";
  51. try {
  52. // 读取服务器返回过来的json字符串数据
  53. str = EntityUtils.toString(result.getEntity(), "utf-8");
  54. // 把json字符串转换成json对象
  55. jsonResult = JSONObject.parseObject(str);
  56. } catch (Exception e) {
  57. logger.error("post请求提交失败:" + url, e);
  58. }
  59. }
  60. } catch (IOException e) {
  61. logger.error("post请求提交失败:" + url, e);
  62. } finally {
  63. httpPost.releaseConnection();
  64. }
  65. return jsonResult;
  66. }
  67. /**
  68. * post请求传输String参数 例如:name=Jack&sex=1&type=2
  69. * Content-type:application/x-www-form-urlencoded
  70. *
  71. * @param url
  72. * url地址
  73. * @param strParam
  74. * 参数
  75. * @return
  76. */
  77. public static JSONObject httpPost(String url, String strParam) {
  78. // post请求返回结果
  79. CloseableHttpClient httpClient = HttpClients.createDefault();
  80. JSONObject jsonResult = null;
  81. HttpPost httpPost = new HttpPost(url);
  82. httpPost.setConfig(requestConfig);
  83. try {
  84. if (null != strParam) {
  85. // 解决中文乱码问题
  86. StringEntity entity = new StringEntity(strParam, "utf-8");
  87. entity.setContentEncoding("UTF-8");
  88. entity.setContentType("application/x-www-form-urlencoded");
  89. httpPost.setEntity(entity);
  90. }
  91. CloseableHttpResponse result = httpClient.execute(httpPost);
  92. // 请求发送成功,并得到响应
  93. if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  94. String str = "";
  95. try {
  96. // 读取服务器返回过来的json字符串数据
  97. str = EntityUtils.toString(result.getEntity(), "utf-8");
  98. // 把json字符串转换成json对象
  99. jsonResult = JSONObject.parseObject(str);
  100. } catch (Exception e) {
  101. logger.error("post请求提交失败:" + url, e);
  102. }
  103. }
  104. } catch (IOException e) {
  105. logger.error("post请求提交失败:" + url, e);
  106. } finally {
  107. httpPost.releaseConnection();
  108. }
  109. return jsonResult;
  110. }
  111. /**
  112. * 发送get请求
  113. *
  114. * @param url
  115. * 路径
  116. * @return
  117. */
  118. public static JSONObject httpGet(String url) {
  119. // get请求返回结果
  120. JSONObject jsonResult = null;
  121. CloseableHttpClient client = HttpClients.createDefault();
  122. // 发送get请求
  123. HttpGet request = new HttpGet(url);
  124. request.setConfig(requestConfig);
  125. try {
  126. CloseableHttpResponse response = client.execute(request);
  127. // 请求发送成功,并得到响应
  128. if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  129. // 读取服务器返回过来的json字符串数据
  130. HttpEntity entity = response.getEntity();
  131. String strResult = EntityUtils.toString(entity, "utf-8");
  132. // 把json字符串转换成json对象
  133. jsonResult = JSONObject.parseObject(strResult);
  134. } else {
  135. logger.error("get请求提交失败:" + url);
  136. }
  137. } catch (IOException e) {
  138. logger.error("get请求提交失败:" + url, e);
  139. } finally {
  140. request.releaseConnection();
  141. }
  142. return jsonResult;
  143. }
  144. }

Controller:

  1. package com.toov5.controller;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. import com.alibaba.fastjson.JSONObject;
  8. @Controller
  9. @SpringBootApplication
  10. public class AIndexController {
  11. @RequestMapping("/aIndexJsp")
  12. public String AIndexJsp() {
  13. return "aIndex";
  14. }
  15. //使用httpClient进行访问b接口
  16. @RequestMapping("/forwardB")
  17. @ResponseBody //这里一定要为 json形式!!! jsp中的ajax访问的路径
  18. public JSONObject forwardB() {
  19. JSONObject result = HttpClientUtils.httpGet("http://b.toov5.com:8081/getBInfo");
  20. return result;
  21. }
  22. public static void main(String[] args) {
  23. SpringApplication.run(AIndexController.class, args);
  24. }
  25. }

1179709-20181121175253478-1534186760.png

B的controller:

  1. package com.toov5.controller;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import javax.servlet.http.HttpServletResponse;
  5. import org.springframework.boot.SpringApplication;
  6. import org.springframework.boot.autoconfigure.SpringBootApplication;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. @RestController
  10. @SpringBootApplication
  11. public class BIndexController {
  12. @RequestMapping("/getBInfo")
  13. public Map<String, Object> getBInfo(HttpServletResponse response){
  14. //告诉浏览器 允许跨域 这段代码应该放在过滤器里面的
  15. // response.setHeader("Access-Control-Allow-Origin", "*"); //*代表所有 可以a.toov5.com专门的
  16. //提供给Ajax嗲用
  17. Map<String,Object> result = new HashMap<String, Object>();
  18. result.put("code", 200);
  19. result.put("msg", "登录成功");
  20. return result;
  21. }
  22. public static void main(String[] args) {
  23. SpringApplication.run(BIndexController.class, args);
  24. }
  25. }

Nginx 方案:

api.toov5.com/a

api.toov5.com/b

  1. 通过Nginx 转发到不同的 项目

Zuul方案:

  1. 类似Nginx 修改Zuul的配置yml

不管访问A项目还是B项目 首先保证域名端口号统一

请求先到Nginx 判断域名相同 项目名字不同 转发到某个项目

发表评论

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

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

相关阅读

    相关 Spring解决问题方案

    项目中需要前后端分离部署,所以需要解决跨域的问题。 跨域可以在前端通过 JSONP 来解决,但是 JSONP 只可以发送 GET 请求,无法发送其他类型的请求,在 REST