Ajax跨域问题完全解决方案

一、概念

1. 跨域问题产生原因:

    ① 浏览器限制
    ② XHR(XMLHttpRequest)请求

2. 解决思路:

在这里插入图片描述

二、简单的解决方案

1. 禁止浏览器检查:

  在命令行模式下,键入如下命令打开谷歌浏览器,可以禁止浏览器检查,避免跨域问题。

chrome --disable-web-security --user-data-dir=g:\google-temp

  :谷歌浏览器49版本号之前只需要输入 chrome --disable-web-security ,49版本号之后需要多输入 --user-data-dir=g:\google-temp,这个文件夹是我们自己新建的,相当于一个保存个人信息的文件夹不能使用谷歌默认的文件夹。

2. Jsonp方式:

  前端发送Jsonp请求,后端也需做响应修改,但是在SpringBoot 2.x以后已被弃用。
  Jsonp的弊端
    1. 服务端需要改动代码支持
    2. 只支持get请求
    3. 发送的不是XHR请求(XHR请求支持一些特性,诸如异步、事件)

三、从架构的角度解决


1. 常见的JAVAEE架构解决方案:

在这里插入图片描述
  一次请求的基本流程:客户端的请求首先发送到Http服务器(Apache或Nginx等),Http服务器会判断客户端的请求是静态请求(不涉及用户数据的请求,诸如图片、js、css等)还是动态请求(调用后端接口)。
  如果是静态请求,Http服务器处理完毕后直接返回给客户端,不用经过Tomcat等应用服务器;如果是动态请求,Http服务器转发请求给Tomcat等应用服务器,Tomcat处理完毕后返回给Http服务器,最后Http服务器再返回给客户端。

2. 被调用方解决跨域 - Filter解决:
   2.1 简单请求和非简单请求:

    在具体解决跨域问题之前,有一个重要的概念首先要了解,就是简单请求非简单请求
    简单请求:请求方法为GET、HEAD、POST。请求头无自定义头,Content-Type为text/plain、multipart/form-data、application/x-www-form-urlencoded之一。
    非简单请求:请求方法为PUT、DELETE。发送Json格式参数的Ajax请求,带自定义头的Ajax请求。
    了解了简单请求和非简单请求的区别之后,这些会对跨域问题有什么影响呢?
    :对于简单请求来说,请求会直接发送到服务端;而对于非简单请求来说,浏览器会预检查,如下:
在这里插入图片描述
    postJson这个请求第一次是OPTIONS,这代表浏览器会预检查,检查成功后才会发到服务端(如图,第二次是POST请求)。当我们的请求是非简单请求时,服务端在响应头补充设置Access-Control-Allow-HeadersAccess-Control-Max-Age(浏览器缓存信息的时长)。

   2.2 不涉及Cookie的请求:

    思路:在服务端设置响应头(HttpServletResponse)来解决跨域问题。
在这里插入图片描述
在这里插入图片描述
  代码解释
    Access-Control-Allow-Origin:调用方(客户端)的域名,* 代表所有。
    Access-Control-Allow-Methods:调用方(客户端)请求的方法,如GET、POST、PUT、DELETE等,* 代表所有。
  :如果只是个别接口需要设置跨域,也可直接在Controller层设置响应头(HttpServletResponse),如下:
在这里插入图片描述

   2.3 涉及Cookie的请求:

    思路:涉及Cookie的跨域问题,服务端设置响应头时要注意,Access-Control-Allow-Origin要设置具体的域名,不能使用 * 代替。代码如下:
在这里插入图片描述
  :Cookie是被调用方的

3. 被调用方解决跨域 - Nginx解决:
   3.1 第一步:配置host文件

在这里插入图片描述
  b.com 代表我们被调用方的域名。

   3.2 第二步:配置Nginx

在这里插入图片描述
Nginx常用命令(Win环境):

 1. 测试Nginx配置文件是否正确

nginx.exe -t

 2. 启动Nginx

start nginx.exe

 3. 重启Nginx(一般用于修改配置文件后)

nginx.exe -s reload

 4. 停止Nginx

nginx.exe -s stop
   3.3 第三步:启动测试

  启动前端、Nginx、服务端,测试结果如下:
在这里插入图片描述
在这里插入图片描述
  :通过响应头里的Server:nginx/1.16.0,我们可以看出 http://b.com/test/get1 是经Nginx转发到Tomcat又返回给前端的。我们平时也可观察Server字段的值,就能得知是否使用了Nginx这种Http服务器(例如,当Server: Apache-Coyote/1.1时,可知并没有使用Nginx,只使用了Tomcat)。

4. 被调用方解决跨域 - Apache解决:
   4.1 第一步:配置host文件

在这里插入图片描述
  b.com 代表我们被调用方的域名。

   4.2 第二步:配置httpd.conf

  下载解压缩Apache2.4,打开conf/httpd.conf文件,打开我们需要的模块:

LoadModule headers_module modules/mod_headers.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
   4.3 第三步:配置httpd-vhosts.conf

   打开conf/extra/httpd-vhosts.conf文件,配置虚拟主机:
在这里插入图片描述

   4.4 第四步:启动测试

   执行bin/httpd.exe
在这里插入图片描述

5. 被调用方解决跨域 - Spring解决:

  利用spring-web包里的 @CrossOrigin注解配置:

    1. 配置到类上,类里的所有方法都允许跨域
在这里插入图片描述
    2. 配置到方法上,该方法允许跨域
在这里插入图片描述
    3. 允许cookie的跨域配置
在这里插入图片描述

6. 调用方解决跨域 - Nginx解决:

    反向代理被调用方的应用服务器。

   6.1 第一步:配置host文件

在这里插入图片描述
  a.com 代表我们调用方的域名。

   6.2 第二步:配置Nginx

在这里插入图片描述

   6.3 第三步:修改前端页面地址

      把绝对地址改为相对地址。
在这里插入图片描述

   6.4 第四步:启动测试

在这里插入图片描述
    :这样前端的请求就是本域请求,就不存在跨域问题了。

7. 调用方解决跨域 - Apache解决:

    反向代理被调用方的应用服务器。

   7.1 第一步:配置host文件

在这里插入图片描述
  a.com 代表我们调用方的域名。

   7.2 第二步:配置httpd-vhosts.conf

在这里插入图片描述

   7.3 第三步:修改前端页面地址

在这里插入图片描述

   7.4 第四步:启动测试

   执行bin/httpd.exe
在这里插入图片描述

四、总结

     该项目代码仓库地址:https://gitee.com/wxj1994/cross-ajax

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值