AJAX跨域最全解决方案

Posted 程序论

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AJAX跨域最全解决方案相关的知识,希望对你有一定的参考价值。

回复“资源”获取独家整理的学习资源!


什么是ajax跨域问题

 

        跨域问题来自于浏览器同源策略的限制,包括DOM同源限制和ajax同源限制,本文探讨的是ajax跨域。ajax跨域指的是一个页面的ajax只能请求和当前页面同源的数据,如果发现请求到的数据不符合要求,浏览器就会阻止返回的数据。所谓同源,指的是协议、域名、端口号都必须完全相同(同一ip的不同域名也是跨域)。同源策略的主要目的是防止csrf攻击,它可以有效地避免由于恶意攻击带来的危险,浏览器器同源策略使得网络访问更加安全。

        但是,实际开发与生产中,常常获取使用来自其他站点的资源,这时候就需要发起跨域请求,这时候就需要使用特殊的方法来处理,使得我们能够获得想要的数据。

        由此可知,跨域仅限于浏览器中,是由于浏览器对不同源数据的拦截产生的,跨域有时候是不可避免的,我们需要采取措施实现跨域请求。

 

 

AJAX跨域最全解决方案

AJAX跨域最全解决方案

1.浏览器 需用户配置

        但意义不大,不可能配置每个客户端的浏览器。

2.XHR-->JSONP

$.ajax({ url:"http://localhost:8080//test//get1", dataType:"jsonp", success:function(data){     console.log(data); }});

        当ajax异步请求增加dataTpe:“jsonp”参数后,发现浏览器控制台没有报错,成功执行了,但通过对比后发现

        1.发出去的请求类型在浏览器可以看到是script类型的,浏览器是不会校验的。普通的ajax请求是xhr类型的。

        2.返回的类型不同:普通的ajax请求content-type是json,而jsonp的请求content-type是js脚本。

AJAX跨域最全解决方案

        AJAX跨域最全解决方案

        JSONP解决方案, 有很多弊端, 无法满足现在的开发要求,所以JSONP用的越来越少了,所以重点放在第三点。

3.跨域

AJAX跨域最全解决方案

 

     3.1 被调用方解决

        被调用方支持跨域解决思路:基于http协议关于跨域方面的要求而做的修改,从a域名调用b域名时,在b域名返回的信息里加些字段,告诉浏览器b允许a调用。浏览器通过校验就不会报跨域安全问题。

      


AJAX跨域最全解决方案



           简单请求:先执行后判断

            非简单请求:先发出一个预检命令,然后在发出请求。先判断后执行。

        3.1.1Filter解决方案

                    添加一个Class 实现 javax.servlet.Filter

AJAX跨域最全解决方案

 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {   HttpServletResponse res = (HttpServletResponse)response; HttpServletRequest req = (HttpServletRequest)request; String origin = req.getHeader("Origin");   if( !org.springframework.util.StringUtils.isEmpty(origin) ){ //带cookie的时候 Origin必须是全匹配 , 不能使用* res.addHeader("Access-Control-Allow-Origin", origin); } String header = req.getHeader("Access-Control-Request-Headers");   //支持所有自定义头 if( !org.springframework.util.StringUtils.isEmpty(header)){ res.addHeader("Access-Control-Request-Headers",header); } res.addHeader("Access-Control-Allow-Methods", "*"); //options预检命令 res.addHeader("Access-Control-Allow-Headers", "Content-Type"); //options预检缓存 res.addHeader("Access-Control-Max-Age", "3600"); //enable cookie res.addHeader("Access-Control-Allow-Credentials", "true");  chain.doFilter(request, response); }

 

    3.1.2 nginx解决方案

        首先,先修改本地的host文件

        打开 C:WindowsSystem32driversetc 路径,打开目录下的host文件,添加 127.0.0.1 traffic.com,表示被调用方的域名。

        AJAX跨域最全解决方案

        然后配置虚拟主机,打开nginx的目录,打开conf文件下的nginx.conf文件,

        在最后添加 include vhost/*.conf;

        AJAX跨域最全解决方案

 

         [注:vhosts目录需手动创建]

        然后在vhost文件夹下添加配置文件 xxx.conf ,并编辑添加内容为

server{  #监听80端口 listen 80; #域名 server_name traffic.com;  location /{ #所有的请求转到 localhost8080 proxy_pass http://localhost:8080/;  add_header Access-Control-Allow-Methods *; #options预检缓存 add_header Access-Control-Max-Age 3600; #enable cookie add_header Access-Control-Allow-Credentials true; #带cookie的时候 Origin必须是全匹配 , 不能使用* add_header Access-Control-Allow-Origin $http_origin; #支持所有自定义头 add_header Access-Control-Allow-Headers $http_access_control_request_headers;  if ($request_method = OPTIONS){ return 200; } }}


                然后打开命令提示符,进入到nginx目录下,输入 nginx -t

 

                AJAX跨域最全解决方案

                如图所示即修改配置成功,可以输入 start nginx.exe 启动 nginx 

                或 输入 nginx -s reload 重新启动nginx

                最后通过 ajax异步请求 nginx配置后的域名 http://traffic.com/test/get1

                成功。

                最后输入 nginx -s stop 停止 nginx

        3.1.3 apache解决方案

            首先打开 apache目下的 conf/httpd.conf 文件,

            以vhost关键字和proxy关键字查找,

            把几个模块以及conf文件开放出来

            LoadModule vhost_alias_module modules/mod_vhost_alias.so 

            LoadModule proxy_module modules/mod_proxy.so

            LoadModule proxy_http_module modules/mod_proxy_http.so

            LoadModule headers_module modules/mod_headers.so

            LoadModule rewrite_module modules/mod_rewrite.so

            Include conf/extra/httpd-vhosts.conf  

            然后编辑  conf/extra/httpd-vhosts.conf 文件

            添加虚拟主机配置

<VirtualHost *:80> #服务器名 ServerName traffic.com #日志 ErrorLog "logs/traffic.com-error.log" CustomLog "logs/traffic.com-access.log" common #代理域名 ProxyPass / http://localhost:8080/  #把请求头的origin值返回到Access-Control-Allow-Origin字段 Header always set Access-Control-Allow-Origin "expr=%{req:origin}"  #把请求头的Access-Control-Request-Headers值返回到Access-Control-Allow-Headers字段 Header always set Access-Control-Allow-Header "expr=%{req:Access-Control-Reqest-Headers}"  Header always set Access-Control-Allow-Methods "#" Header always set Access-Control-Allow-Credentials "true" Header always set Access-Control-Max-Age "3600"  #处理预检命令OPTIONS,直接返回204 RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.#)$ "/" [R=204,L]</VirtualHost>



            然后cmd 

            cd /apache/bin 

            httpd.exe -k start  

            启动 apache
            测试成功。

            

        3.1.4 spring框架解决方案

                    在类或者方法上添加注解         @CrossOrigin

 

 

    3.2 调用方解决

        调用方隐藏跨域解决思路:当域名不是自己公司的时,可以用此方法解决。通过一个代理,使得从浏览器发出的请求都是a域名的请求,在代理里面把指定的url转到b域名里面,使得在浏览器上看上去就是同一个域名。

AJAX跨域最全解决方案

        

      3.2.1 NGINX反向代理配置解决方案

          

        首先,先修改本地的host文件

        打开 C:WindowsSystem32driversetc 路径,打开目录下的host文件,添加 127.0.0.1 trafficInvoke.com,表示被调用方的域名。

AJAX跨域最全解决方案

        然后在vhost文件夹下添加配置文件 xxx.conf ,并编辑添加内容为

        

server{  #监听80端口 listen 80; #域名 server_name trafficInvoke.com;  location /{ #所有的请求转到 localhost8081 proxy_pass http://localhost:8081/; }  #反向代理地址 ajaxserver location /ajaxserver{ proxy_pass http://localhost:8080/test/get1; }}

 

      3.2.3 APACHE反向代理配置解决方案

<VirtualHost *:80> #服务器名 ServerName trafficInvoke.com #日志 ErrorLog "logs/trafficInvoke.com-error.log" CustomLog "logs/trafficInvoke.com-access.log" common #反向代理地址 ajaxserver ProxyPass /ajaxserverapache http://localhost:8080/test/get1  #代理域名 ProxyPass / http://localhost:8081/</VirtualHost>



AJAX跨域最全解决方案


AJAX跨域最全解决方案

● 

● 

● 

● 

● 



汇聚精彩的免费学习教程



关注公众号领取学习资源


喜欢本文,点个“在看”告诉我



以上是关于AJAX跨域最全解决方案的主要内容,如果未能解决你的问题,请参考以下文章

ajax跨域,这应该是最全的解决方案了

ajax跨域,这应该是最全的解决方案了

Ajax 跨域,这应该是最全的解决方案了

ajax跨域,这应该是最全的解决方案了

史上最全的Ajax

PHP中运用jQuery的Ajax跨域调用实现代码