jsonp详解及跨域请求
什么是JSONP?
JSON是一种轻量级的数据传输格式语言,被广泛应用于当前Web应用中。JSON格式数据的编码和解析基本在所有主流语言中都被实现,所以现在大部分前后端分离的架构都以JSON格式进行数据的传输。
那么什么是JSONP?
jsonp就是动态创建script,与ajax无关。是一种非官方跨域数据交互协议。
请求方:frank.com 的前端程序员(浏览器)
响应方:jack.com 的后端程序员(服务器)
- 请求方创建 script,src 指向响应方,同时传一个查询参数 ?callbackName=yyy
 - 响应方根据查询参数callbackName,构造形如浏览器接收到响应,就会执行 yyy.call(undefined, '你要的数据')
- yyy.call(undefined, '你要的数据')
 - yyy('你要的数据')
这样的响应 
 - 那么请求方就知道了他要的数据
 
这就是 JSONP
约定:callbackName -> callback
   yyy -> 随机数 frank12312312312321325()
JSONP的作用
首先我们要知道浏览器同源策略这个概念。为了保证用户访问的安全,现代浏览器使用了同源策略,即不允许访问非同源的页面。在ajax中,不允许请求非同源的URL,比如www.a.com下的一个页面,其中的ajax请求是不允许访问www.b.com/c.php这样一个页面的。
ajax请求受同源策略影响,js文件的调用则不受跨域与否的限制,因此如果想通过纯web端跨域访问数据,只能在远程服务器上设法将json数据封装进js格式的文件中,供客户端调用和进一步处理,这就是jsonp协议的原理。该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
JSONP具体实现
- 远程服务器remoteserver.com根目录下有个remote.js文件代码
 - 本地服务器localserver.com下有个jsonp.html页面代码
 - 在jsonp.html页面定义一个函数,然后在远程remote.js中传入数据进行调用
 - 运行之后查看结果,页面成功弹出提示窗口,显示本地函数被跨域的远程js调用成功,并且还接收到了远程js带来的数据。
 - 只要服务端提供的js脚本是动态生成的,这样调用者可以传一个参数过去告诉服务端 “我想要一段调用XXX函数的js代码,请你返回给我”,于是服务器就可以按照客户端的需求来生成js脚本并响应。
 
//remote.js文件代码
alert('我是远程文件');
localHandler({"result":"我是远程js带来的数据"});
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
//jsonp.js文件代码
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
jQuery实现JSONP调用:
$.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
             jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
             success: function(json){
                 alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
             },
             error: function(){
                 alert('fail');
             }
         });
jQuery ajax方式以jsonp类型发起跨域请求,其原理跟<script>脚本请求一样,因此使用jsonp时也只能使用GET方式发起跨域请求。跨域请求需要服务端配合,设置callback,才能完成跨域请求。
ajax与jsonp的异同
- ajax和jsonp这两种技术在调用方式上”看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装。但实际jsonp和ajax没关系。
 - ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加。
 - ajax无法跨域请求,可以用多种请求 方法;jsonp可以跨域请求,但只能用get请求。
 
跨域请求和同源策略
- 同源策略,只有协议+端口+域名 一模一样的才允许法AJAX请求。
 - 因为AJAX可以读取响应内容,浏览器必须保证同源策略。
 

jsonp详解及跨域请求的更多相关文章
- 【转】solr+ajax智能拼音详解---solr跨域请求
		
本文转自:http://blog.csdn.net/wangzhaodong001/article/details/8529090 最近刚做完solr的ajax智能拼音.总结一下. 前端:jQuery ...
 - Django使用jsonp和cors解决跨域请求问题
		
1.使用jsonp的方式解决跨域请求的问题 我启动两个django项目,然后使用的端口不一样,在项目1中通过ajax发请求给项目2,然后接受项目2发送过来的数据 先看项目1的ajax的代码 $(&qu ...
 - 跨域 - jsonp轻松搞定跨域请求
		
1.jsonp轻松搞定跨域请求 vue中使用axios,遇到跨域我就蒙逼了.第一次真正意义上的尝试使用jsonp js中用 var myscript = document.createElement( ...
 - JavaScript系列----AJAX机制详解以及跨域通信
		
1.Ajax 1.1.Ajax简介 Ajax简介这一部分我们主要是谈一下ajax的起源,ajax是什么?因为这些是跟技术无关的.所以,大多细节都是一笔带过. Ajax的起源? Ajax一词源于2005 ...
 - 【从零开始搭建自己的.NET Core Api框架】(五)由浅入深详解CORS跨域机制并快速实现
		
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
 - 详解 CORS跨域的几种不同实现方式
		
CORS 定义 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),它允许浏览器向跨源服务器,发出XMLHttpRequ ...
 - 详解JS跨域问题
		
什么是跨域? 概念:只要协议.域名.端口有任何一个不同,都被当作是不同的域. JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
 - 详解js跨域
		
什么是跨域? 概念:只要协议.域名.端口有任何一个不同,都被当作是不同的域. 对于端口和协议的不同,只能通过后台来解决.URL 说明 是否允许通信 http://www.a.com/a.js http ...
 - php中ajax跨域请求---小记
		
php中ajax跨域请求---小记 前端时间,遇到的一个问题,情况大约是这样: 原来的写法: 前端js文件中: $.ajax({ type:'get', url:'http://wan.xxx.c ...
 
随机推荐
- 转:为什么浏览器的user-agent字符串以'Mozilla'开头呢?
			
本文转自:https://blog.csdn.net/S_gy_Zetrov/article/details/79463093 感谢sgyzetrov翻译 如果熟悉元素审查的童鞋,很多都会发现requ ...
 - CTF流量分析题大全(掘安攻防平台)
			
突然想做一下流量分析题,记得掘安攻防实验室上面有很多的流量分析题目,故做之 流量分析题一般使用的都是wireshark,(流量分析工具中的王牌 夺取阿富汗 说了分析http头,所以直接过滤http协议 ...
 - jenkins+git部署环境,出现Failed to connect to repository : Command "git ls-remote -h http://gitlab.xxxxx.git HEAD" returned status code 128stdout:  stderr: fatal: repository 'http://gitlab.xxxxx.git' not fou
			
1.部署jenkins+git源码管理的方式,源码管理报128stdout 源码管理出现如下错误: Failed to connect to repository : Command "gi ...
 - 算法数据结构——数的深搜和广搜(dfs和bfs)
			
leetcode104 二叉树的最大深度 https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/ 深度搜索分两种:递归(使用栈) ...
 - PC微信[多开+免扫码+防撤回撤回提示+转存语音+自动收款+远程命令]
			
PC端微信玩出了新花样,主要技术为Hook技术 有兴趣的小伙伴可以去了解下hook钩子技术 版本介绍: 增加转存语音到MP3(保存你重要的语音数据) 增加表图转存; 增加自动收转账和自动回复; 增加远 ...
 - buuctf-[网鼎杯 2018]Fakebook 1
			
这道题,也是费了很大的劲,慢慢理解慢慢消化,今天,才开始把wp写出来 首先我们先扫描一波目录,用dirsearch扫一手,发现有robots.txt文件 dirseach自带的字典在db目录下,使用格 ...
 - NOI Online 题解
			
T1 对\(t_i = 1\)的边,将\(u_i, v_i\)连一条边权为\(1\)的边.否则连一条边权为\(0\)的边. 对于每一个连通块,若图中不存在一条边权之和为奇数的圈,则可以将这个连通块二染 ...
 - maven私有仓库搭建(nexus)
			
搭建是参考博客:https://blog.csdn.net/zn353010922/article/details/79441122 切换到nexus目录的bin下 启动.状态.停止:./nexus ...
 - rsync 参数说明及使用参数笔记
			
第1章 rsync 命令简介 rsync 是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据镜像同步备份的优秀工具. 1.1.1 语法格式 三种模式: 1)本地模式 rsync [选项] ...
 - Python编码相关
			
1.#coding=utf-8的作用 作用是这个文件代码的编码格式,如果没有声明代码中不能出现中文字符,包括注释中也不能出现.否则会报错SyntaxError: Non-ASCII character ...