爱站屋博客 - 好东西不私藏,大家一起分享!关于博客 留言板

网站首页 模板插件 正文

我产资源无限好片线路ajax跨域详细介绍

2019-08-03 模板插件 1434 ℃

我产资源无限好片线路ajax跨域详细介绍-第1张图片-【秒速时时彩开奖结果】爱站屋博客

AJAX跨域

[db:标签]:本文部分容均来自慕课网。@慕课网:https://www.imooc.com

课程介绍

  ●什么是AJAX跨域问题

  ●产生AJAX跨域问题的原因

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

什么是AJAX跨域问题

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

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

AJAX跨域场景

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

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

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

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

AJAX跨域原因

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

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

  ●XHR(XMLHttpRequest)请求

AJAX跨域问题解决思路

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

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

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

编写测试代码

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

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

  ●引入前端Jasmine测试框架

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

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

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

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

  ●举个很简单的例:在编写网页的时候,<img src = www.xxxx.xxxx/ >,URL不是本域的还是可以正常获取该图片的

解决跨域问题的思路

我产资源无限好片线路ajax跨域详细介绍-第2张图片-【秒速时时彩开奖结果】爱站屋博客

环境搭建

2-1 后端项目

代码编写

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

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>     <groupId>com.myimooc</groupId>     <artifactId>ajax-server</artifactId>     <version>0.0.1-SNAPSHOT</version>     <packaging>jar</packaging>     <name>ajax-server</name>     <description>Demo project for Spring Boot</description>     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>2.0.1.RELEASE</version>         <relativePath/> <!-- lookup parent from repository -->     </parent>     <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>         <java.version>1.8</java.version>     </properties>     <dependencies>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>             <scope>test</scope>         </dependency>     </dependencies>     <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>             </plugin>         </plugins>     </build> </project>

2.编写AjaxServerStart类

package com.myimooc.ajax.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /**  * <br>  * 标题: 启动类<br>  * 描述: AJAX跨域讲解后端项目<br>  *  * @author zc  * @date 2018/04/18  */ @SpringBootApplication public 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; /**  * <br>  * 标题: REST请求响应POJO类<br>  * 描述: 封装请求响应结果<br>  *  * @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.*; /**  * <br>  * 标题: 测试控制器<br>  * 描述: 提供REST服务<br>  * 使用 @CrossOrigin 注解支持跨域,可以放到类或方法上面  * @author zc  * @date 2018/04/18  */ @RestController @RequestMapping("/test") //@CrossOrigin public 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如下

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>     <groupId>com.myimooc</groupId>     <artifactId>ajax-client</artifactId>     <version>0.0.1-SNAPSHOT</version>     <packaging>jar</packaging>     <name>ajax-client</name>     <description>Demo project for Spring Boot</description>     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>2.0.1.RELEASE</version>         <relativePath/> <!-- lookup parent from repository -->     </parent>     <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>         <java.version>1.8</java.version>     </properties>     <dependencies>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>         <dependency>             <groupId>org.webjars</groupId>             <artifactId>jquery</artifactId>             <version>3.3.0</version>         </dependency>         <dependency>             <groupId>org.webjars</groupId>             <artifactId>jasmine</artifactId>             <version>2.5.0</version>         </dependency>     </dependencies>     <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>             </plugin>         </plugins>     </build> </project>

2.编写index.html

<!DOCTYPE html> <html> <head>     <meta charset="UTF-8">     <title>Index</title>     <link rel="stylesheet" type="text/css" href="/webjars/jasmine/2.5.0/jasmine.css">     <script src="/webjars/jquery/3.3.0/jquery.min.js"></script>     <script src="/webjars/jasmine/2.5.0/jasmine.js"></script>     <script src="/webjars/jasmine/2.5.0/jasmine-html.js"></script>     <script src="/webjars/jasmine/2.5.0/boot.js"></script> </head> <body> <a href="#" onclick="get1()">发生get1请求</a> <script>     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);         });     }); </script> </body> </html>

3.编写application.properties

server.port=8081

4.编写AjaxClientStart类

package com.myimooc.ajax.client; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public 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; /**  * <br>  * 标题: JSONP 全局处理<br>  * 描述: 统一处理JSONP<br>  *  * @author zc  * @date 2018/04/18  */ @ControllerAdvice public 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; /**  * <br>  * 标题: 服务端解决跨域<br>  * 描述: 使用Filter<br>  *  * @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; /**  * <br>  * 标题: 配置类<br>  * 描述: 注册CrosFilter<br>  *  * @author zc  * @date 2018/04/18  */ @Configuration public 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在最后面增加下面的内容即可

<VirtualHost *:80>     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] </VirtualHost>

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在最后面增加下面的内容即可

<VirtualHost *:80>     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 </VirtualHost>

课程总结

4-1 课程总结

课程总结

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

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

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

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

我产资源无限好片线路ajax跨域详细介绍-第3张图片-【秒速时时彩开奖结果】爱站屋博客

以上就是ajax跨域详细介绍的详细内容,更多请关注php中文网其它相关文章!


猜你喜欢

本文暂时没有评论哦(●'◡'●)

欢迎 发表评论:

:如果评论未出现,请刷新网页,谢谢合作!

会员中心
搜索
ip签名图
    IP签名图
网站分类
标签列表
文章归档
站点信息
  • 文章总数:112038
  • 页面总数:3
  • 分类总数:12
  • 标签总数:629
  • 评论总数:2060
  • 浏览总数:1241363
爱站云安全认证