为了账号安全,请及时绑定邮箱和手机立即绑定

ajax跨域完全讲解

晓风轻 全栈工程师
难度中级
时长 1小时40分
学习人数
综合评分9.67
119人评价 查看评价
9.7 内容实用
9.6 简洁易懂
9.7 逻辑清晰
  • /*
    一.浏览器多管闲事-----------------------------------------------------搞定浏览器: 让浏览器滚,不判断
       1.启动浏览器的时候加参数
       2.浏览器跨域插件
    二.浏览器判断类型: XHR (XMLHttpRequest)-------------------------------发送类型不是XHR, JSONP就是利用这一条.
       JSONP一个非官方的协议, JSONP的弊端:
       1.JSONP需要后台配合, 要有一个参数, 默认是?callback=JQuery1234567...   JSONP返回的类型是:javascript, 而非json
       2.只可以发送get请求
       3.发送的不是XHR请求(这也是它可以跨域的原因),没有回调及事件的特性
    三.浏览器判断跨域: 协议, 域名, 端口, 任何一个不一样就是跨域-----------1.服务器告诉浏览器可以跨域. 2.前端通过代理欺骗浏览器是同一个域名
       1.后端处理:
          a)应用服务器(TOMCAT)--Filter,
             "Access-Control-Allow-Origin": "http://localhost:8081"
             "Access-Control-Allow-Methods": "GET"
             "Access-Control-Allow-Headers": "Content-Type, custom-header1, custom-header2" //非简单请求每次会发出去两次请求,预检命令(OPTIONS)和真正的请求
             "Access-Control-Max-Age": "3600" //预检命令(OPTIONS)为1个小时, 这样1个小时内就不用发送两次请求
             "Access-Control-Allow-Credentials": "true" //不是"Access-Control-Allow-Origin": "*"就无敌了, 带Cookie的请求就行不通!
          b)HTTP服务器(NGINX)
             配置比apache简单些
          c)HTTP服务器(APACHE)
             相对nginx复杂一些
          d)Spring框架解决方案
             @CrossOrigin
       2.前端处理(隐藏跨域):
          a)反向代理-NGINX配置
             在请求的时候写相对路径就行, 浏览器认为请求是同域的, 不会做跨域判断. 后端处理时, 请求地址都是绝对路径
          b)反向代理-APACHE配置
    
    以上一,二,三个条件必需同时满足, 才会生跨域问题!
    问答:
    -> 为什么已经返回200了还报错: 因为是先发送, 浏览器再判断是否跨域. 如果存在跨域条件, 则报错.
    */


    查看全部
    10 采集 收起 来源:课程总结

    2018-09-02

  • JSONP的弊端:

    • 服务器需要改动代码支持-如果调用的接口不是我们自己的,那么改动就很麻烦

    • 只支持GET方法,JSONP是通过动态创建一个script发送请求的,而script只支持GET方法

    • 发送的不是XHR请求,XHR有许多新的特性,如异步、各种事件等,JSONP则没有


    查看全部
    4 采集 收起 来源:json解决跨域

    2018-06-26

  • 从服务端解决跨域问题:

    (1)被调用方解决跨域问题,被调用方修改代码解决。

    (2)调用方解决跨域,调用方修改Apache或者Nginx静态服务器,通过静态服务器隐藏调用请求返回给前台,前台以为是同一个地址和端口的请求就解决了跨域问题。


    一个请求是怎么被处理的:当一个请求从浏览器发出的时候,他会先到中间的http服务器或者叫静态服务器主要是由(apache/nginx)来处理的。中间的静态服务器收到请求后会判断是静态请求还是动态请求,和用户数据有关的就是动态请求,如图片,css,js就是静态请求,中间的静态服务器发现是静态请求时就会把请求直接处理,然后直接返回到客户端,如果是动态请求,请求从客户端发起到了中间的http服务器,中间的http服务器会把请求转发到后台的应用服务器处理完后再返回给中间的http服务器,http服务器再把请求转发到客户请求。

    查看全部
  • jsonp的实现原理:

    1. jsonp的请求类型是script,而非xhr,这样浏览器就不会做安全校验;

    2. jsonp的返回类型是js,而非json;

    3. jsonp请求携带一个前后台约定的参数(eg:callback),便于让后台识别是jsonp请求,后台则返回js数据而非json数据

    查看全部
    2 采集 收起 来源:json解决跨域2

    2018-11-16

  • 4、Filter解决跨域方案

    问题1:浏览器是先执行请求还是先判断跨域?

        浏览器请求-->判断响应中是否有允许跨域-->发现不允许跨域,阻止跨域

        说明:当执行跨域请求时,浏览器会提示当前接口不被允许,这说明浏览器已发出了当前请求,但是它的的响应内容被拦截;如果在Response header中的Access-Control-Allow-Origin设置的允许访问源不包含当前源,则拒绝数据返回给当前源。

    问题2:判断当前请求是否是跨域请求的方法?

        通过查看当前请求的Request Headers 中是否存在Origin属性,当前属性存储的是当前域的信息


    在被调用方解决跨域(支持跨域)通过自定义Filter来实现:

        1、在SpringBoot工程创建自定拦截器CrosFilter,如图:



        2、 注册自定拦截器CrosFilter,作用于全局如图:


    问题3:什么是简单请求和非简单请求?

        说明:浏览器在发送跨域请求时会先判断当前请求是不是简单请求,如果是简单请求浏览器则会先执行请求,再判断是否支持跨域;如果是非简单请求它会先发送一个预检命令(即OPTIONS请求),检查通过后再把当前请求发出去。

        1、简单请求:

            方法为GET、HEAD、POST的请求,并且请求头(header)里面没有自定义头;Content-Type为text/plain、multipart/form-data、application/x-www-form-urlencoded。

        2、非简单请求:

            方法为PUT、DELETE的请求,发送JSON格式的ajax请求、带自定义请求头的ajax请求。

        例子:发送JSON格式的ajax请求

        

    问题4:Access-Control-Allow-Headers是什么?有什么作用?

        响应头部 Access-Control-Allow-Headers 用于 preflight request (预检请求)中,列出了将会在正式请求的 Access-Control-Expose-Headers 字段中出现的首部信息。简单首部,如 simple headers、Accept、Accept-Language、Content-Language、Content-Type (只限于解析后的值为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 三种MIME类型(不包括参数)),它们始终是被支持的,不需要在这个首部特意列出。


    问题5:Access-Control-Max-Age是什么?

    浏览器的同源策略,就是出于安全考虑,浏览器会限制从脚本发起的跨域HTTP请求(比如异步请求GET, POST, PUT, DELETE, OPTIONS等等),所以浏览器会向所请求的服务器发起两次请求,第一次是浏览器使用OPTIONS方法发起一个预检请求,第二次才是真正的异步请求,第一次的预检请求获知服务器是否允许该跨域请求:如果允许,才发起第二次真实的请求;如果不允许,则拦截第二次请求。Access-Control-Max-Age用来指定本次预检请求的有效期,单位为秒,,在此期间不用发出另一条预检请求。

        例如:res.addHeader("Access-Control-Max-Age", "3600"),表示隔60分钟才发起预检请求




    查看全部
  • 当浏览器要发送跨域请求时,如果请求是复杂请求,浏览器会先发送一个options预检命令即一个options请求,当该请求通过时才会再发送真正的请求。

    该option请求会根据请求的信息去询问服务端支不支持该请求。比如发送的数据是json类型(通过content-type设置)的话,会携带一个请求头Access-Control-Request-Headers: content-type去询问支不支持该数据类型,如果支持,则请求就会通过,并发送真正的请求


    查看全部
  • 总结

    跨域产生的原因:

    1. 浏览器限制。如果浏览器发现请求是跨域的时候,就会做校验,如果校验不通过就会报跨域的错误

    2. 跨域。发出去的请求只要域名、端口、协议中的任意一个与当前域不同的时候,都会发生跨域

    3. 发送的XHR(XMLHTTPRequest)请求。如果发送的不是xhr请求,无论是否跨域,浏览器都不会报错

    只有这三种原因同时满足时,才会发生跨域

    解决跨域的方法

    1. 浏览器角度。让浏览器不做校验,浏览器的设置跨域,在浏览器的属性设置页面的目标输入框加上--disable-web-security。这样浏览器将不会去做校验了。但是每个人都需要去改动,不建议使用。

    2. 发送xhr请求角度。让跨域的请求不发送xhr请求,就不会再报错了。办法是使用jsonp:jsonp是非官方协议,是前后端的一种约定,前端使用ajax发送请求,dataType为jsonp,并且带一个参数(默认是callback),当后台发现这个参数之后,就知道这是一个jsonp请求,就会把原本返回json对象编程js返回,js代码是一个函数的执行,函数名是callback的参数值,函数的参数是原本的json对象。缺点:1).只支持get方法请求;2).需要服务器修改代码;3).发送的不是xhr请求

    3. 在跨域角度。1).被调用方解决:在响应头增加指定字段,告诉浏览器,允许调用,这种方法的原理是从根源支持跨域的。各种解决方式,请参考详细解决笔记;2).调用方解决:这种解决办法原理是隐藏跨域。使用代理,在同一个域请求不同的url地址,转发到不同的域。


    查看全部
    3 采集 收起 来源:课程总结

    2018-06-21

  • 一、解决跨域的思路:

    1.被调用方解决-支持跨域(根据http协议关于跨域方面的要求,增加响应头信息,告诉浏览器允许被跨域调用)

    (1)使用filter解决

    res.addHeader("Access-Control-Allow-Origin", "http://localhost:8081"); //设置允许http://localhost:8081域访问,*表示所有域都能访问

    res.addHeader("Access-Control-Allow-Methods", "GET");//设置允许GET方法访问,*表示所有方法

    (2)nginx解决方案

    (3)APACHE解决方案

    (4)Spring解决方案 加@CrossOrigin注解即可

    2.调用方使用代理做调用解决跨域问题-隐藏跨域

    (1)使用反向代理

    反向代理:访问同一个域名的两个url,会去到两个不同的服务器


    二、简单请求和非简单请求

    • 简单请求:先执行后判断

    工作中常见的简单请求:

    方法为:GET,HEAD,POST

    请求header里面:无自定义头

    Content-Type为以下几种:text/plain,multipart/form-data,application/x-www-form-urlencoded

    • 非简单请求:先发预options预检命令,通过后再发跨域请求

    res.addHeader("Access-Control-Allow-Headers", "Content-Type");//允许预检命令

    res.addHeader("Access-Control-Max-Age", "3600");//预检命令缓存秒数

    工作中常见的非简单请求:put,delete的请求,发送json格式的请求,带自定义头的请求


    三、带Cookie的跨域请求,response中需要设置

    res.addHeader("Access-Control-Allow-Credentials", "true");

    res.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");//带Cookie时Access-Control-Allow-Origin需要全匹配,不能用通配符

    当多个域名都需要带Cookie跨域访问时,从Filter里面拿到Origin信息,把这个字段写入到Access-Control-Allow-Origin里面

    String origin = req.getHeader("Origin");

    if(!StringUtils.isEmpty(origin)) {

    res.addHeader("Access-Control-Allow-Origin", origin);

    }

    注意:1. 发送的Cookie是被调用方的Cookie,不是调用方的Cookie document.cookie="cookie1=xiaofengqing"这样就能新加入一个cookie了  2.Access-Control-Allow-Origin不能使用*


    四、带自定义头的跨域

    //支持所有自定义头

    String headers = req.getHeader("Access-Control-Request-Headers");

    if(!StringUtils.isEmpty(headers)) {

    res.addHeader("Access-Control-Allow-Headers",headers);

    }


    查看全部
    6 采集 收起 来源:课程总结

    2018-05-03

  • 被调用方解决跨域问题,被调用方修改代码解决。

    调用方解决跨域,调用方修改Apache或者Nginx静态服务器,通过静态服务器隐藏调用请求返回给前台,前台以为是同一个地址和端口的请求就解决了跨域问题。

    查看全部
  • nginx.exe -t  检查配置是否成功

    start nginx.exe 启动nginx

    nginx.exe -s reload 重新载入修改的配置



    hosts 映射本地域名    127.0.0.1 b.com


    server{

        listen 80;

        server_name b.com;  请求发起方 即 浏览器客户端

        location /{

                proxy_pass http://localhost:8080/;    服务器地址

                add_header Access-Control-Allow-Methds *;

                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_request_headers;


                if ($request_method = OPTIONS){

                    return 200;

                }

        }

    }

    查看全部
  • 一、http会话session依赖于cookie, sessionid存放在cookie中。

    二、ajax

    1、$.ajax({

        type: "get",

        xhrFields: {

            widthCredentials: true // 发送ajax请求的时候会带上cookie

        }

    })

    2、cookie是加在被调用方。

    https://img1.sycdn.imooc.com//5d6bd4a50001420610810534.jpg

    服务端就是被调用方,而客户端就是调用方。在浏览器的控制台中通过document.cookie=""  来设置cookie。


    3、读cookie只能读到本域的。

    4、带cookie时,后台代码注意以下2点:

    (1)带cookie的时候,Access-Control-Allow-Origin,必须是全匹配,如http://localhost:8081, 不能是 *,否则报错,如下:

    https://img1.sycdn.imooc.com//5d6bd58f0001da3713720394.jpg


    (2)带cookie进行跨域时,需要设置以下请求头:

    res.addHeader("Access-Control-Allow-Credentials", "true")


    查看全部
  • 简单请求和非简单请求

    1.简单请求是先请求,浏览器再判断是否是跨域;而非简单请求要先发送一个预检命令,检查通过之后才会真正的把跨域请求发出去

    https://img1.sycdn.imooc.com//5b20d3fc0001e2c106900579.jpg

    2.非简单请求常见的是发送json格式的请求,如图contentType为“application/json;charset=utf-8”https://img1.sycdn.imooc.com//5b20d5b70001ea4706440351.jpg

    最后的结果如下,返回了两个请求,一个是OPTIONS,另一个是POST请求,其中的OPTIONS就是一个预检命令,成功了之后才会发送后面的跨域请求

    https://img1.sycdn.imooc.com//5b20d6e700017ede12160078.jpg

    3.预检命令的缓存。因为这种非简单请求每次都会发送两次请求,其实效率是比较低的,但是如果能缓存预检命令的话,会响应的提高效率

    在服务器中,添加一个响应头信息,告诉浏览器在截下来的一个小时可以缓存信息,就不需要再发送预检命令

    https://img1.sycdn.imooc.com//5b20ddae0001647408530207.jpg


    查看全部
  • jsonp解决跨域问题的原理(区别):

    ①普通请求,发送请求时,请求类型type默认为 xhr  ;jsonp的请求类型为 script ,不会被浏览器认为是跨域异常;

    ②普通请求返回的数据类型默认为 json 格式;而 jsonp 的请求返回的数据类型为 javascript 的脚本;

    ③普通请求的地址后面没有携带任何数据;而jsonp请求的地址后面携带了 callback为键的一组键值对数据;由下列图片可知,

    当前端被设置为jsonp格式后,在后端中使用切面实现 jsonp 的格式化接口;该接口声明当返回的数据有callback这个值时,将返回的数据以jsonp的格式返回给前端,避免出现数据类型不一致的问题。


    查看全部
    1 采集 收起 来源:json解决跨域2

    2019-09-01

  • 我们知道非简单请求, 每次会发出两次请求, 这会影响性能. HTTP协议增加了个响应头, 可以让我们在服务端设置`Access-Control-Max-Age`来缓存预检请求, 比如说我们可以设置为3600m, 也就是一小时客户端只会在第一次的时候发送两个请求, 接下来一个小时内`OPTIONS`请求就被缓存起来了.

    查看全部
  • JSONP是一个非官方协议,它是一个约定,约定了一个请求的参数里如果包含指定的参数(默认是callback)这就是一个JSONP请求,服务发现是一个JSONP请求时就会把返回的值由原来的JSON对象改变JS代码,JS的代码的内容是函数调用的形式。他的函数名是callback参数的值,他的函数的参数是原来 要返回的JSON对象

    查看全部
    2 采集 收起 来源:json解决跨域

    2019-05-08

首页上一页1234567下一页尾页

举报

0/150
提交
取消
课程须知
需要具备基本的前后台开发技术
老师告诉你能学到什么?
AJAX跨域产生的原因和解决思路 系统的基本部署架构和跨域的关系 http服务器nginx和apache的重要作用和跨域的2种解决思路 jsonp的工作机制和优缺点 前台测试框架Jasmine的使用

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!