ajax跨域详细介绍

ajax跨域详细介绍

ajax跨域

说明:本文部分内容均来自慕课网。@慕课网:https://www.imooc.com

课程介绍

  ●什么是ajax跨域问题

  ●产生ajax跨域问题的原因

  ●解决ajax跨域问题的思路和方法

什么是ajax跨域问题

  ●简单来说,就是前端调用后端服务接口时

  ●如果服务接口不是同一个域,就会产生跨域问题

ajax跨域场景

  ●前后端分离、服务化的开发模式

  ●前后端开发独立,前端需要大量调用后端接口的场景

  ●只要后端接口不是同一个域,就会产生跨域问题

  ●跨域问题很普遍,解决跨域问题也很重要

ajax跨域原因

  ●浏览器限制:浏览器安全校验限制

  ●跨域(协议、域名、端口任何一个不一样都会认为是跨域)

  ●XHR(XMLHttpRequest)请求

ajax跨域问题解决思路

  ●浏览器:浏览器取下跨域校验,实际价值不大

  ●XHR:不使用XHR,使用JSONP,有很多弊端,无法满足现在的开发要求

  ●跨域:被调用方修改支持跨域调用(指定参数);调用方修改隐藏跨域(基于代理)

编写测试代码

  ●被调用方后端代码编写:Spring Boot

  ●调用方前端代码编写:Jquery

  ●引入前端Jasmine测试框架

为什么会发生产生跨域问题?

上面的图也很清晰了,因为浏览器为了安全(同源),本身就限制了。

  ●当我们发送XMLHttpRequest请求的时候,如果请求的是别的域(主机域名、端口)不同时,那么就会产生跨域问题(客户端无法获取服务端返回的数据)

值得注意的是:跨域的问题是发生在XMLHttpRequest请求的,也就是说,不是XMLHttpRequest请求是不会有跨域问题的

  ●举个很简单的例子:在编写网页的时候,ajax跨域详细介绍,URL不是本域的还是可以正常获取该图片的

解决跨域问题的思路

1081645-20180806100009761-1165936588.png

环境搭建

2-1 后端项目

代码编写

1.创建名为ajax-server的maven工程pom如下

    4.0.0    com.myimooc    ajax-server    0.0.1-SNAPSHOT    jar    ajax-server    Demo project for Spring Boot            org.springframework.boot        spring-boot-starter-parent        2.0.1.RELEASE                         UTF-8        UTF-8        1.8                            org.springframework.boot            spring-boot-starter-web                            org.springframework.boot            spring-boot-starter-test            test                                                    org.springframework.boot                spring-boot-maven-plugin                        

登录后复制

2.编写AjaxServerStart类

package com.myimooc.ajax.server;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * 
 * 标题: 启动类
 * 描述: ajax跨域讲解后端项目
 * * @author zc * @date 2018/04/18 */@SpringBootApplicationpublic class AjaxServerStart {    public static void main(String[] args) {        SpringApplication.run(AjaxServerStart.class, args);    }}

登录后复制

3.编写ResultBean类

package com.myimooc.ajax.server.vo;import java.io.Serializable;/** * 
 * 标题: REST请求响应POJO类
 * 描述: 封装请求响应结果
 * * @author zc * @date 2018/04/18 */public class ResultBean implements Serializable{    private static final long serialVersionUID = 7867107433319736719L;    private String data;    public ResultBean(String data) {        this.data = data;    }    public String getData() {        return data;    }    public void setData(String data) {        this.data = data;    }}

登录后复制

4.编写TestController类

package com.myimooc.ajax.server.controller;import com.myimooc.ajax.server.vo.ResultBean;import com.myimooc.ajax.server.vo.User;import org.springframework.web.bind.annotation.*;/** * 
 * 标题: 测试控制器
 * 描述: 提供REST服务
 * 使用 @CrossOrigin 注解支持跨域,可以放到类或方法上面 * @author zc * @date 2018/04/18 */@RestController@RequestMapping("/test")//@CrossOriginpublic class TestController {    @GetMapping("/get1")    public ResultBean get1() {        System.out.println("TestController.get1");        return new ResultBean("get1ok");    }    @PostMapping("/postJson")    public ResultBean postJson(@RequestBody User user) {        System.out.println("TestController.postJson");        return new ResultBean("postJson" + user.getName());    }    @GetMapping("/getCookie")    public ResultBean getCookie(@CookieValue(value = "cookie1") String cookie1) {        System.out.println("TestController.getCookie");        return new ResultBean("getCookie" + cookie1);    }    @GetMapping("/getHeader")    public ResultBean getHeader(            @RequestHeader("x-header1") String header1,            @RequestHeader("x-header2") String header2) {        System.out.println("TestController.getHeader");        return new ResultBean("getHeader" + header1+header2);    }}

登录后复制

2-2 前端项目

代码编写

1.创建名为ajax-client的maven工程pom如下

    4.0.0    com.myimooc    ajax-client    0.0.1-SNAPSHOT    jar    ajax-client    Demo project for Spring Boot            org.springframework.boot        spring-boot-starter-parent        2.0.1.RELEASE                         UTF-8        UTF-8        1.8                            org.springframework.boot            spring-boot-starter-web                            org.webjars            jquery            3.3.0                            org.webjars            jasmine            2.5.0                                                    org.springframework.boot                spring-boot-maven-plugin                        

登录后复制

2.编写index.html

nbsp;html>        Index                    发生get1请求    function get1() {        $.getJSON("http://localhost:8080/test/get1").then(            function (res) {                console.log(res);            }        )    }    // 每一个测试用例的超时时间    jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;    // 请求的接口地址前缀    var base = "http://localhost:8080/test";    // 测试模块    describe("AJAX讲解", function () {        // 测试方法        it("get1请求", function (done) {            // 服务器返回的结果            var result;            $.getJSON(base + "/get1").then(                function (res) {                    result = res;                }            );            // 由于是异步请求,需要使用setTimeout来校验            setTimeout(function () {                expect(result).toEqual({                    "data":"get1ok"                });                // 校验完成,通知jasmine框架                done();            },100);        });        // // 测试方法        // it("jsonp请求", function (done) {        //     // 服务器返回的结果        //     var result;        //     $.ajax({        //         url: base + "/get1",        //         dataType: "jsonp",        //         jsonp:"callback2",        //         success: function (res) {        //             result = res;        //         }        //     });        //        //     // 由于是异步请求,需要使用setTimeout来校验        //     setTimeout(function () {        //         expect(result).toEqual({        //             "data":"get1ok"        //         });        //        //         // 校验完成,通知jasmine框架        //         done();        //     },100);        // });        // 测试方法        it("postJson请求", function (done) {            // 服务器返回的结果            var result;            $.ajax({                url:base+"/postJson",                type:"POST",                contentType:"application/json;charset=utf-8",                data:JSON.stringify({name:"testName"}),                success:function(res){                    result = res;                }            });            // 由于是异步请求,需要使用setTimeout来校验            setTimeout(function () {                expect(result).toEqual({                    "data":"postJsontestName"                });                // 校验完成,通知jasmine框架                done();            },100);        });        it("getCookie请求", function (done) {            // 服务器返回的结果            var result;            $.ajax({                url:base+"/getCookie",                xhrFields:{                    // 发送 AJAX 请求时带上 cookie                    withCredentials:true                },                success:function(res){                    result = res;                }            });            // 由于是异步请求,需要使用setTimeout来校验            setTimeout(function () {                expect(result).toEqual({                    "data":"getCookietestName"                });                // 校验完成,通知jasmine框架                done();            },100);        });        it("getHeader请求", function (done) {            // 服务器返回的结果            var result;            $.ajax({                url:base+"/getHeader",                headers:{                    "x-header1":"AAA"                },                beforeSend:function(xhr){                   xhr.setRequestHeader("x-header2","BBB")                },                success:function(res){                    result = res;                }            });            // 由于是异步请求,需要使用setTimeout来校验            setTimeout(function () {                expect(result).toEqual({                    "data":"getHeaderAAABBB"                });                // 校验完成,通知jasmine框架                done();            },100);        });    });

登录后复制

3.编写application.properties

server.port=8081

登录后复制

4.编写AjaxClientStart类

package com.myimooc.ajax.client;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class AjaxClientStart {    public static void main(String[] args) {        SpringApplication.run(AjaxClientStart.class, args);    }}

登录后复制

5.启动AjaxServerStart和AjaxClientStart,并访问http://localhost:8081,点击发生get1请求,产生跨域问题如下

解决跨域

3-1 禁止检查

Chrome浏览器的跨域设置

Windows方法

  参考文档:https://www.cnblogs.com/laden…

  使用说明:在属性页面中的目标输入框里加上:–disable-web-security –user-data-dir=C:MyChromeDevUserData

Mac OS方法

  参考文档:http://blog.csdn.net/justinji…

  使用说明:用命令行打开 Google Chrome:open -a “Google Chrome” –args –disable-web-security

3-2 使用JSONP

代码编写

1.编写JsonpAdvice类

package com.myimooc.ajax.server.controller;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;/** * 
 * 标题: JSONP 全局处理
 * 描述: 统一处理JSONP
 * * @author zc * @date 2018/04/18 */@ControllerAdvicepublic class JsonpAdvice extends AbstractJsonpResponseBodyAdvice{    public JsonpAdvice() {        // 与前端约定好回调方法名称,默认是callback        super("callback2");    }}

登录后复制

2.修改index.html

// 测试方法        it("jsonp请求", function (done) {            // 服务器返回的结果            var result;            $.ajax({                url: base + "/get1",                dataType: "jsonp",                jsonp:"callback2",                success: function (res) {                    result = res;                }            });            // 由于是异步请求,需要使用setTimeout来校验            setTimeout(function () {                expect(result).toEqual({                    "data":"get1ok"                });                // 校验完成,通知jasmine框架                done();            },100);        });

登录后复制

JSONP的弊端

服务器需要改动代码支持只支持GET发送的不是XHR请求

3-3 支持跨域

常见的JavaEE架构

跨域解决方向

  ●被调用方解决

  ●基于支持跨域的解决思路

  ●基于Http协议关于跨域的相关规定,在响应头里增加指定的字段告诉浏览器,允许调用

  ●跨域请求是直接从浏览器发送到被调用方

  ●修改被调用方的Http服务器

调用方解决

  ●基于隐藏跨域的解决思路

  ●跨域请求不会浏览器直接发送到被调用方

  ●而是从中间的Http服务器(Apache、Nginx)转发过去

  ●修改调用方的Http服务器

被调用方支持跨域

  ●【重点】Web应用服务器(Tomcat、Netty、WebLogic或应用程序)实现

  ●Http服务器(Nginx)配置实现

  ●Http服务器(Apache)配置实现

使用Filter解决

编写代码

1.编写CrosFilter类

package com.myimooc.ajax.server.config;import org.springframework.util.StringUtils;import javax.servlet.*;import javax.servlet.FilterConfig;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * 
 * 标题: 服务端解决跨域
 * 描述: 使用Filter
 * * @author zc * @date 2018/04/18 */public class CrosFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @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 (!StringUtils.isEmpty(origin)){            // 支持任何域名的跨域调用 且 支持带cookie(是被调用方域名的cookie,而不是调用方的cookie)            res.addHeader("Access-Control-Allow-Origin",origin);        }        // 指定允许的域,带cookie时,origin必须是全匹配,不能使用 *//        res.addHeader("Access-Control-Allow-Origin","http://localhost:8081");        // 允许所有域,但不能满足带 cookie 的跨域请求//        res.addHeader("Access-Control-Allow-Origin","*");        // 支持所有自定义头        String headers = req.getHeader("Access-Control-Allow-Headers");        if (!StringUtils.isEmpty(headers)){            // 允许所有header            res.addHeader("Access-Control-Allow-Headers",headers);        }        // 允许所有header//        res.addHeader("Access-Control-Allow-Headers","*");        // 指定允许的方法//        res.addHeader("Access-Control-Allow-Methods","GET");        // 允许所有方法        res.addHeader("Access-Control-Allow-Methods","*");        // 允许浏览器在一个小时内,缓存跨域访问信息(即上面三个信息)        res.addHeader("Access-Control-Max-Age","3600");        // 启用 cookie        res.addHeader("Access-Control-Allow-Credentials","true");        chain.doFilter(request,response);    }    @Override    public void destroy() {    }}

登录后复制

2.编写FilterConfig类

package com.myimooc.ajax.server.config;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * 
 * 标题: 配置类
 * 描述: 注册CrosFilter
 * * @author zc * @date 2018/04/18 */@Configurationpublic class FilterConfig {    @Bean    public FilterRegistrationBean registrationBean(){        FilterRegistrationBean filter = new FilterRegistrationBean();        filter.addUrlPatterns("/*");        filter.setFilter(new CrosFilter());        return filter;    }}

登录后复制

3.启动AjaxServerStart和AjaxClientStart,并访问http://localhost:8081,跨域解决

简单请求与非简单请求

  ●简单请求:浏览器先发送真正的请求后检查

  ●请求方法:GET、HEAD、POST的一种

  ●请求header:无自定义header;Content-Type为:text/plain、multipart/form-data、application/x-www-form-urlencoded的一种

  ●非简单请求:浏览器先发预检命令,检查通过后,才发送真正的请求

  ●常见的有:PUT、DELETE

  ●其它条件:发送Json格式的请求、带自定义header的请求

  ●预检命令:浏览器检测到跨域请求, 会自动发出一个OPTIONS请求, 就是所谓的预检(preflight)请求。当预检请求通过的时候,才发送真正的请求。

Nginx配置

  ●修改主机hosts文件增加映射本地域名:127.0.0.1 b.com(表示被调用方的域名)

  ●在conf目录下创建vhost目录

  ●修改nginx.conf在最后面增加一行代码:include vhost/*.conf;

  ●在vhost目录下创建b.com.conf

  ●启动niginx,访问b.com/test/get1

编写b.com.conf

server{    listen 80;    server_name b.com;    location /{        proxy_pass http://localhost:8080/;        add_header Access-Control-Allow-Methods *;        add_header Access-Control-Max-Age 3600;        add_header Access-Control-Allow-Credentials true;        add_header Access-Control-Allow-Origin $http_origin;        add_header Access-Control-Allow-Headers $http_access_control_allow_headers;        if ($request_method = OPTIONS){            return 200;        }    }}

登录后复制

Apache配置

  ●修改conf/httpd.conf找到LoadModule vhost_alias_module module/mod_vhost_alias.so取消注释

  ●修改conf/httpd.conf找到LoadModule proxy_module module/mod_ proxy.so取消注释

  ●修改conf/httpd.conf找到LoadModule proxy_http_module module/mod_ proxy_http.so取消注释

  ●修改conf/httpd.conf找到LoadModule headers_module module/mod_ headers.so取消注释

  ●修改conf/httpd.conf找到LoadModule rewrite_module module/mod_ rewrite.so取消注释

  ●修改conf/httpd.conf找到Include conf/extra/httpd-vhosts.conf取消注释

  ●修改conf/extra/httpd-vhosts.conf在最后面增加下面的内容即可

    ServerName b.com    ErrorLog "logs/b.com-error.log"    CustomLog "logs/b.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-Allow-Headers值返回到Access-Control-Allow-Headers字段    Header always Access-Control-Allow-Headers "expr=%{Access-Control-Allow-Headers}"    Header always set Access-Control-Allow-Methods "*";    Header always set Access-Control-Max-Age "3600";    Header always set Access-Control-Allow-Credentials ""true";    # 处理预检命令OPTIONS,直接返回204    RewriteEngine On    RewriteCond %{REQUEST_METHOD}OPTIONS    RewriteRule ^(.*)$"/" [R=204,L]

登录后复制

Spring框架支持

在类或方法上使用注解@CrossOrigin即可支持跨域

3-4 隐藏跨域

  ●使用Nginx反向代理实现

  ●修改主机hosts文件增加映射本地域名:127.0.0.1 a.com

  ●在vhost目录下创建a.com.conf

  ●启动niginx,访问a.com/ajaxserver/get1

编写a.com.conf

server{    listen 80;    server_name a.com;    location /{         proxy_pass http://localhost:8081/;    }    location /ajaxserver{         proxy_pass http://localhost:8080/test/;    }}

登录后复制

使用Apache反向代理实现

修改conf/extra/httpd-vhosts.conf在最后面增加下面的内容即可

    ServerName a.com    ErrorLog "logs/a.com-error.log"    CustomLog "logs/a.com-access.log" common    ProxyPass / http://localhost:8081/    ProxyPass /ajaxserverapache http://localhost:8080/test

登录后复制

课程总结

4-1 课程总结

课程总结

  ●产生原因:主要是浏览器对Ajax请求的限制

  ●解决思路:JSONP、支持跨域、隐藏跨域

  ●核心原理:了解Http协议关于跨域方面的规定

  ●解决方法:使用Filter、Nginx正反向代理、Apache正反向代理、Spring框架支持

1081645-20180806105920865-862144044.png

以上就是ajax跨域详细介绍的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2729949.html

(0)
上一篇 2025年3月8日 00:11:57
下一篇 2025年2月26日 13:57:37

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Ajax完整详细教程(一)

    Ajax 简介 ajax 由 html、javascript™ 技术、dhtml 和 dom 组成,这一杰出的方法可以将笨拙的 web 界面转化成交互性的 ajax 应用程序。它是一种构建网站的强大方法。 Ajax 尝试建立桌面应用程序的功…

    2025年3月8日
    200
  • Ajax完整详细教程(三)

    在本系列的 上篇文章 中,我们将详细介绍 xmlhttprequest 对象,它是 ajax 应用程序的中心,负责处理服务器端应用程序和脚本的请求,并处理从服务器端组件返回的数据。由于所有的 ajax 应用程序都要使用xmlhttprequ…

    2025年3月8日 编程技术
    200
  • ajax请求的五个步骤

    ajax请求的五个步骤     第一步,创建XMLHttpRequest对象 第二步,注册回调函数 第三步,配置请求信息,open(),get 第四步,发送请求,post请求下,要传递的参数放这 第五步,创建回调函数 //第一步,创建XML…

    2025年3月8日
    200
  • ajax获取网页添加到div中的方法

    ajax获取网页添加到div中的方法 1:利用DOM获取该 div 的 ID,然后清空该DIV的内容(如果你需要接着里面的内容添加可不要清空);需要注意点是清空最好用“ empty()  ”; 2: 把  async设成true ,否则又一…

    2025年3月8日
    200
  • 原生JS封装AJAX方法

    ajax大家每天都在用,jquery库对ajax的封装也很完善、很好用,下面我们看一下它的内部原理,并手动封装一个自己的ajax库。 一、原理 原生Ajax的发送需要四步: 1) 创建Ajax对象: XMLHttpRequest 2) 设置…

    编程技术 2025年3月7日
    200
  • ajax请求方式有几种

    1、$.ajax()返回其创建的 xmlhttprequest 对象 $.ajax() 只有一个参数:参数key/value对象,包含各配置及回调函数信息。 如果你指定了dataType选项,那么需要保证服务器返回正确的MIME信息,(如 …

    2025年3月7日
    200
  • Ajax 是干嘛用的?

    Ajax 是干嘛用的? Ajax是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术,并且可以通过在后台与服务器进行少量数据交换,可以使网页实现异步更新。 Ajax 有缺点 使用Ajax的…

    2025年3月7日
    200
  • Ajax接收JSON数据

    1.   Ajax接收JSON数据 json:javascript对象表示法(javascript object notation)。json是一种存储和交换文本信息的语法。因为json比xml更轻量,效率更高,更易解析,所以在ajax中前…

    2025年3月7日
    200
  • 如何实现AJAX请求?

    如何实现ajax请求? 1、创建XMLHttpRequest实例; var xhr;if(window.XMLHttpRequest) {  //ie7+,firefox,chrome,safari,opera  xhr = new XML…

    2025年3月7日
    200
  • 深入了解ajax(图文详解)

    1.1 什么是ajax: Ajax即“Asynchronous Javascript And XML”(异步JavaScript 和XML),是指一种创建交互式网页应用的网页开发技术。Ajax=异步JavaScript和XML(标准通用标记…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论