跨域及JSONP原理

什么是跨域:a.com 域名下的js无法操作b.com或是c.a.com域名下的对象

为什么浏览器要引入跨域问题?

跨域问题来源于浏览器的同源策略,为啥要有这个策略呢?

为了安全。假设现在有a.com 和b.com 两个域,如果没有同源策略的限制,那么a.com就可以随随便便就去b.com 里面拿东西,甚至一些cookie信息(常用于存储登录信息),那么a.com只需要一段代码就可以获取你的cookie信息,从而冒充你的身份去登录网站。

当使用 AJAX 跨域访问资源 会受到同源策略影响,浏览器会报错。

啥算跨域?

页面本身都有协议,域名,端口。当协议,域名,端口这三个有任意一个不一样就算跨域。

这里的跨域访问资源是那些资源呢(只有访问这些资源时浏览器不会显示给我们)?

  1. 后端接口的数据
  2. 其他域的cookie
  3. 其他域的缓存

当访问在有src属性的,或者部分href属性的,即使跨域浏览器也会返回给我们。只有跨域访问上面的资源浏览器才会报错。

事实上跨域是可以发出请求,浏览器也是可以接受到返回给我们的信息。但接受到数据之后发现页面的域和请求的域不同,所以判定跨域,不会把结果传递给我们的代码。也就是说同源策略是浏览器的一个安全策略。

那当有需要去访问别人服务器接口等这样的需求时,怎样解决同源策略的这种限制也就是跨域问题。

有人会不理解为啥浏览器地址栏直接访问接口不是跨域,而AJAX访问接口就是跨域问题

你的AJAX所在的所在的位置是一个域,而访问的服务器接口是一个域。那在地址栏里是在客户端向往服务器里发型请求只存在服务端一个域。例如:你打开一个地址可以说就是请求了一个域的内容,http://www.baidu.com/xxx,你可以理解为www.baidu.com,就是一个域,这个时候你在这个地址内发出一个请求http://www.baidukuayu.com/xxx,那请求的就是www.baidukuayu.com.这两个地址的主域不一样可以为第二个请求跨域了。

在说一下为啥本地文件访问服务器也会出现跨域

因为本地文件(file:///C:/Users/master/Desktop/canvas/变换.html)前面的file也是个协议,是用来浏览器打开本地文件使用的文件协议。这也就解释了为啥会跨域因为协议不同嘛。而大多数网络相关的请求都是http或者https协议,所以无法进行与网络相关的操作(跨域,ajax,访问cookie等)

so,我们想办法绕过这个file协议,基本上每个编辑器都提供了插件,他在你本地代码启动的时候,可以隐式的返回一个服务。 例如在vscode的live server插件,webStrom 直接点击走上角的小浏览器标识就可以隐式的打开一个服务。

解决跨域问题

  1. 后端配合我们进行跨域

    1. JSONP
    2. 后端设置Access-Control-Allow-Origin属性支持跨域(让服务器告诉浏览器我这个接口所有网站都可以访问)
  2. 后端不配合我们进行跨域
    1. iframe(只能显示,不能控制)
    2. 通过服务器代理中转(原理:跨域只是浏览器的限制,但是我自己的服务器可以去访问被人的接口,我们访问自己的服务器,让自己的服务器去访问别人的接口,然后返回的数据再返回给服务器)

使用jquery JSONP跨域

$.ajax({
            url:"",  //请求地址
            type:"",  //请求方式       data:"",  //要发送给服务器的值
            dataType:"jsonp",//要求服务器返回的数据类型       async:"", //请求是否异步
            success:function(data){  //成功的回调函数
                ......
            }
        })

成功跨域请求数据

我们发现发送请求的地址后面自动加上一个callback参数,而请求回来的jsonp数据的格式正是发送时的callback(json).

JSONP原理:动态创建script标签,使用script的src进行跨域

具体步骤:

  1. 判断请求的与当前页面域是否同源,如果同源正常发送ajax,如果不同源,生成一个script标签
  2. 生成一个随机的callback名字,并生成对应名字的方法。
  3. 设置script的src为要请求的接口,将callback参数拼接在后面。
  4. 后端接收到请求后,开始准备要返回的数据
  5. 后端拼接数据,将要返回的数据用callback包裹起来,将内容返回。
  6. 浏览区接收到内容那个,会当做js代码来执行。
  7. 从而执行第二步生成的方法,这样就接收到后端返回给我们的对象。
  • jsonp选script的src进行跨域的原因?

我们知道带有src属性和部分的href属性是可以跨域的。但是href大多是样式。我们使用带src属性的。带src属性的有audio,video,img ,src,script等,但只有script是可以对数据进行控制,显示等。所以跨域的本质是使用script标签发出请求。例如引入jQuery的cdn:   <script src = https://cdn.bootcss.com/jquery/3.4.1/jquery.js></script>

  • 为什么jsonp都是使用get方式请求?

由于jsonp的原理就是使用script标签进行跨域,而script都是使用get方式请求数据。所以jsonp跨域只能是get方法,即使你设置的post方法,jQuery也会自动转为get方法。但如果你使用jsonp的方式并么有跨域,也就是同源,那么设置的get就是get,post还是post.

  • 使用script便签索然可以引用其他域的资源,浏览器也不会限制,但是,浏览器会将但会的内容,作为代码执行。例如jQuery的cdn返回给我们的是jQuery源码
  • jsonp为什么使用回调函数的方式处理返回的数据,以及为什么script的src后面为啥拼接一个callback参数呢?

在使用jsonp返回数据时,可能是个对象,也可能是个数组,但无论是什么都要给这个对象或数组附上一个名字(引用)以便访问这个数据,例如var a = {name:‘zhang‘},否则让我们怎么使用这个数据。

     var script = document.createElement(‘script‘);
        script.src = "./another.js";
        document.body.appendChild(script);
        console.log(a);
--another.js文件内容。--
var a = {name:‘f‘}  //假设后端返回的数据

    由于动态创建的script是异步加载的。所以访问a为被定义。

    这时候我们就想到回调函数了,等js文件加好了,自动执行岂不是更好,并且还隐藏了返回数据的引用。

var script = document.createElement(‘script‘);
        script.src = "./another.js";
        document.body.appendChild(script);
        function aa(data){
            console.log(data);
        }
--another.js文件内容。--
aa({name:‘dg‘})  //假设后端返回的数据

像这样创建一个函数,返回的数据用上面定义的函数名包裹执行这个已经定义好的函数,并把要返回的数据作为参数传递给要执行的函数。等到js文件加载完自动执行这个函数。

那怎样让后端知道你前端定义好的那个函数名(名字要一致啊,不然怎么执行),这是我们就知道了为啥url后面跟着一个callback参数了。直接把你定义好的函数名拼接在你要访问地址的后面一块传给后端岂不快哉。

  • 默认是在url后加callback,如果想自定义函数的参数名取代默认的callback,可以通过使用$.ajax的jsonp参数
  • jsonp原理代码实现
var $ = {
            ajax : function (options) {
                var url = options.url;
                var type = options.type;
                var dataType = options.dataType;
                // 判断是否同源(协议,域名,端口是否相同)
                var targetProtocol = "";  //目标接口协议
                var targetHost = ""       //目标接口的host(包括协议和端口)
                // 如果url不带http,访问的就是相对路径(同源)
                if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) {
                    var targetUrl = new URL(url);
                    targetProtocol = targetUrl.protocol;
                    targetHost = targetUrl.host;
                } else {
                    targetProtocol = location.protocol;
                    targetHost = location.host;
                }
                // 判断是否是jsonp,如果不是jsonp,直接发送ajax
                if (dataType == "jsonp") {
                    if (location.protocol == targetProtocol && location.host == targetHost) {
                        // 使用ajax
                    }
                    else { //跨域
                        // 随机生成一个callback,并生成对应的方法
                        var callback = "cb" + Math.floor(Math.random() * 1000000);
                        window[callback] = options.success;
                        // 创建script标签
                        var script = document.createElement(‘script‘);
                        // 如果url没有参数
                        if (url.indexOf(‘?‘) != -1) {
                            script.src = url + "&callback=" + callback;
                        }
                        else {//有参数
                            script.src = url + "?callback=" + callback;
                        }
                        // 将script添加到文档中
                        document.body.appendChild(script);
                    }
                }
            }
        }     

      $.ajax({

        url:‘http://developer.duyiedu.com/edu/testJsonp‘,

        type:‘get‘,

        dataType:‘jsonp‘,

        success:function(data){

        console.log(data);

        }

      })

 

原文地址:https://www.cnblogs.com/jiaobaba/p/11610062.html

时间: 2024-10-08 21:01:14

跨域及JSONP原理的相关文章

解决Ajax 跨域问题 - JSONP原理解析

解决Ajax 跨域问题 - JSONP原理解析 为什么会有跨域问题? - 因为有同源策略 同源策略是浏览器的一种安全策略,所谓同源指的是 请求URL地址中的 协议, 域名 和 端口 都相同,只要其中之一不相同就是跨域 同源策略主要为了保证浏览器的安全性 在同源策略下,浏览器**不允许**Ajax跨域获取服务器数据 http://www.example.com/detail.html 跨域请求: http://api.example.com/detail.html 域名不同 http://www.

Ajax跨域:Jsonp原理解析

推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略).这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容. JavaScript这个安全策略在进行多iframe或多窗口编程.以及Ajax编程时显得

跨域请求 JSONP 原理

js 中事先定义好回掉函数,回掉函数的参数就是跨域返回的值 后台返回调用的回掉函数

Ajax 跨域请求 jsonp获取json数据

遇到Ajax的跨域请求出问题 找了中解决办法如下: 参考内容:http://justcoding.iteye.com/blog/1366102 由于受到浏览器的限制,该方法不允许跨域通信.如果尝试从不同的域请求数据,会出现安全错误.如果能控制数 据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误.但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办? 理解同源策略 同源策略阻止从一个域上加载的脚本获取或操作另一个域上的

Java跨域以及实现原理

最近研究了一下跨域,没接触之前我的印象就是配合单点登录的一种方式,后来在网上看到资料才知道不仅仅是这一种,用法很多,具体的可以去网上搜索. 一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面.动态网页.web服务.WCF,只要是跨域请求,一律不准.下面我就在自己本地用8081端口请求8081的接口看看会提示什么吧? 如上图所示,已经被浏览器拦截了,所以现在我们需要换jsonp的方法来获取服务器返回的数据. 服务端的接口如下: @RequestMapping(v

jQuery(三) javascript跨域问题(JSONP解决)

加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回来的值,这就是javascript跨域,其实简单点,之前我们做的ajax,都是在同域中访问,现在只是访问的服务器变成了另外的,不是同一台了.仅此而已.但是这样一变,之前的代码就不能用了. 二.解决javascript跨域问题 解决该问题,有很多种方式,我百度了一下,好像这就属于前端的范畴了,所以我决

JS跨域:jsonp、跨域资源共享、iframe+window.name

JS跨域:jsonp.跨域资源共享.iframe+window.name :https://www.cnblogs.com/doudoublog/p/8652213.html JS中的跨域 请求跨域有好多种, 一.跨域资源共享: 也就是设置服务端的header,可以指定哪些域名可以请求,也是最简单的跨域方式(自我感觉),并且可以支持post等等. //指定允许其他域名访问 'Access-Control-Allow-Origin:*'//或指定域 //响应类型 'Access-Control-A

ajax跨域之jsonp

跨域之jsonp jsonp跨域原理 script便签可以跨域,基于这个机制,可以在A域的页面中定义jsonp函数,script标签返回这个函数的调用 如下代码所示A域页面代码 <body> <div>正在获取数据--</div> <script>function jsonp(data) { document.querySelector('div').innerHTML = data; } </script> <!--向B域请求数据--&g

JavaScript 九种跨域方式实现原理

前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容. 一.什么是跨域? 1.什么是同源策略及其限制内容? 同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到 XSS.CSFR 等***.所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源.同源策略限制内容有: Cookie.LocalStorage.IndexedDB 等存储性内容DOM 节点AJAX 请求发送