【前端】直击源头的让你3秒理解并且会用Jsonp!!!
1. 同源策略
ajax之所以需要“跨域”,罪魁祸首就是浏览器的同源策略。即,一个页面的ajax只能获取这个页面相同源或者相同域的数据。
如何叫“同源”或者“同域”呢?——协议、域名、端口号都必须相同。例如:
http://google.com 和 https://google.com 不同,因为协议不同;
http://localhost:8080 和 http://localhost:1000 不同,因为端口不同;
http://localhost:8080 和 https://google.com 不同,协议、域名、端口号都不同,根本不是一家的。
根据同源策略,我自己做的一个网页 http://localhost:8080/test.html 就无法通过ajax直接获取 http://google.com 的数据。
例如,我用ajax去访问一个不同域的页面,错误结果是这样的:
大家想想,这样其实也有道理。如果没有同源策略,你我都可以随便通过ajax直接获取其他网站的信息,这还不乱套了。。。我自己做一个搜索界面,搜索时直接用ajax从百度获取数据,那不成了小偷了。。。
但是跨域访问是少不了的,http://mail.163.com 的网页可能需要从 http://news.163.com 域下获取新闻信息,那怎么办?——开始咱们的跨域之旅。(当然用iframe也可以实现)
2. 从“盗链”说起
互联网的许多网站之间图片相互盗链,A网站网页的img.src直接链接到B网站的图片地址,这是常有的事儿。说到“盗链”,大家第一想到的可能是如何去防止盗链,今儿咱不管那个。
你再想想“盗链”和“同源策略”这两个词之间有什么关系?——对,矛盾!既然都“同源策略”了,怎么还能“盗链”呢?
世间万物都有矛盾,有矛盾了照样可以和谐共处,并不一定非要你死我活。
重点:<img>的src(获取图片),<link>的href(获取css),<script>的src(获取javascript)这三个都不符合同源策略,它们可以跨域获取数据。因此,你可以直接从一些cdn上获取jQuery,并且你网站上的图片也随时可能被别人盗用,所有最好加上水印!
而我们今天的主角——jsonp——就是因为<script>的src不符合同源策略而来的。
3. JSONP
例如,域名 http://a.com 下有一个 http://a.com/test.html 网页,域名 http://b.com 下有一个 http://b.com/data.html 网页和 http://b.com/alert.js 文件。
引导第一步:简单引用js
编写 http://b.com/alert.js 如下:
alert(123);
对 http://a.com/test.html 编写如下代码:
<script type='text/javascript' src='http://b.com/alert.js'/>
运行 http://a.com/test.html,结果很明显,就是弹出 【123】 。
引导第二步:引用js返回数据
将 http://b.com/alert.js 修改为:
myFn(100);
将 http://a.com/test.html 修改为:
<script type='text/javascript' src='http://b.com/alert.js'/>
<script>
function myFn ( data ) {
alert( data + 'px' );
}
</script>
运行 http://a.com/test.html,结果是弹出【 100px 】,这个应该也没有什么疑问。
引导第三步:已经跨域成功!
第二步中,如果data——即100——是我要跨域在http://b.com下获取的一个数据,那么咱们这不就是已经实现跨域请求了吗!!!
把这个过程再清晰的捋一遍:
- <script>的src不符合同源策略;
- 我通过给<script>的src赋值一个跨域的文件的网址(可能不是一个js文件),这个文件返回的字符串,浏览器会当作javascript来解析;
- 而这段javascript中,就可以包含着我所需要的跨域服务器端的数据;
- 最后,我在本页面定义一个myFn函数用来展示数据,而这段javascript中就可以直接调用myFn函数;
引导第四步:引用html格式
<script>的src不一定仅仅指向javascript文件,可以指向任何地址。例如:
将 http://a.com/test.html 修改为:
<script type='text/javascript' src='http://b.com/data.html'/>
<script>
function myFn ( data ) {
alert( data + 'px' );
}
</script>
将 http://b.com/data.html 编写为:(注意,data.html中就写以下一行代码,多了不写)
myFn(100);
运行 http://a.com/test.html ,结果依然是【 100px 】
其中,“100”就是我们要跨域请求的数据。
引导第五步:动态数据
如果要请求的数据是动态的,那就要在动态页面中编写。
那么我们就让 http://a.com/test.html 去调用一个动态的aspx页面:
<script type='text/javascript' src='http://b.com/data.aspx?callback=myFn'/>
<script>
function myFn ( data ) {
alert( data + 'px' );
}
</script>
大家注意,我们在 src 地址中增加了“?callback=myFn”,意思是把显示数据的函数也动态传过去了,而第二步、第四步都是静态的写在被调用的文件中的。
至于callback参数后台如何接收,如何使用,请接着看:
在 http://b.com 下增加一个 http://b.com/data.aspx 页面,后台代码如下:
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack == false)
{
string callback = "";
if (Request["callback"] != null)
{
callback = Request["callback"];
//服务器端要返回的数据
string data = "1024";
Response.Write(callback + "(" + data + ")");
}
}
}
代码很简单,获取callback参数,然后组成一个函数的形式返回。如果“http://b.com/data.aspx?callback=myFn”调用的话,那么返回的就是" myFn(1024) "。
返回的数据变成动态的了(“1024”),前端页面用于显示数据的函数也编程了动态的了(“callback=myFn”),但是归根结底,形式还是一样的。
引导第六步:调用封装
http://a.com/test.html 中,仅仅有一个<script>静静的躺在那里,执行一次之后,就没有作用了。
而实际情况是,http://a.com/test.html 中,可能随着用户的操作发生若干次的调用。怎么办?——动态增加呗。
function addScriptTag(src) {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.src = src;
document.body.appendChild(script);
}
//需要调用时:
addScriptTag('b.com/data.aspx?callback=myFn');
function myFn (data) {
alert(data + 'px');
}
4. 总结
以前我们引入的是函数,在script里面写的是函数的执行。
现在用jsonp相当于引入函数的执行命令, 在script里面写的是函数声明。
以上层层描述的就是JSONP,你不必去记住它的定义,看明白了上述文字,就全能理解。
重点在于:同源策略 + <script>的src不属于同源策略 + 通过<script>的src指向的文件返回服务器端数据。
【前端】直击源头的让你3秒理解并且会用Jsonp!!!的更多相关文章
- 阿里前端测试题--关于ES6中Promise函数的理解与应用
今天做了阿里前端的笔试题目,原题目是这样的 //实现mergePromise函数,把传进去的数组顺序先后执行,//并且把返回的数据先后放到数组data中 const timeout = ms => ...
- 学习前端的菜鸡对JS 的classList理解
classList 在早期的时候要添加,删除类 需要用className去获取,然后通过正则表达式去判断这个类是否存在. 代码上去会有点麻烦,现在有了classList 就方便了很多. ——————— ...
- html页面3秒后自动跳转的方法有哪些
在进行web前端开发实战练习时,我们常常遇到一种问题就是,web前端开发应该如何实现页面N秒之后自动跳转呢?通过查找相关html教程,总结了3个方法: 方法1: 最简单的一种:直接在前面<hea ...
- 精读《Serverless 给前端带来了什么》
1. 引言 Serverless 是一种 "无服务器架构",让用户无需关心程序运行环境.资源及数量,只要将精力 Focus 到业务逻辑上的技术. 现在公司已经实现 DevOps 化 ...
- web前端优化
在谈到Web优化之前,我们回到一个更原始的问题,Web前端的本质是什么.我的理解是: 将信息快速并友好的展示给用户并能够与用户进行交互.快速的意思就是在尽可能短的时间内完成页面的加载,试想一下当你在淘 ...
- BAT 前端开发面经 —— 吐血总结 前端相关片段整理——持续更新 前端基础精简总结 Web Storage You don't know js
BAT 前端开发面经 —— 吐血总结 目录 1. Tencent 2. 阿里 3. 百度 更好阅读,请移步这里 聊之前 最近暑期实习招聘已经开始,个人目前参加了阿里的内推及腾讯和百度的实习生招聘, ...
- 收益 or 挑战?Serverless 究竟给前端带来了什么
作者 | 黄子毅(紫益) 阿里前端技术专家 导读:前端开发者是最早享受到 "Serverless" 好处的群体,因为浏览器就是一个开箱即用.甚至无需为计算付费的环境!Serverl ...
- Web前端开发推荐阅读书籍
前言 前端工程师在中国兴起也就5年左右,以前公司里没有专门前端工程师的这个职位,很多前端方面的任务都是由全栈工程师来完成,有的基础一点的后台或者设计的帮助分担一些.但是随着互联网的快速发展,特别是所谓 ...
- 前端代码标准最佳实践:CSS
前端工程师对写标准的前端代码的重视程度很高.这些最佳标准实践并不是那个权威组织发布的,而是由大量的前端工程师们在实践过程中的经验总结,目的在于提高代码的可读性,可维护性和性能.那么接着上一篇,我们再来 ...
随机推荐
- 使用pyquery是遇到的一个403的问题
在网上爬虫时,本地windows下运行pyquery代码正常,但是在linux下运行时一直报错 403 Forbidden.刚开始的代码如下 from pyquery import PyQuery a ...
- MySql--学习成长过程
MySql--学习成长过程 模拟测试: QQ数据库管理 一.创建数据库并添加关系和测试数据 1 ##创建QQ数据库,完成简单的测试 2 3 #创建数据库 4 DROP DATABASE IF EXIS ...
- div内元素的居中
1.如果是一行文字(不超过一行) parent{ text-align:center; line-height:div高度; } 2.如果是div内其他类型元素 parent{ height:xxxp ...
- Bob Waters - Twenty Years
We were just children and grown up closeHow we made it this far only god knowsWe bend the rulesSmash ...
- 【python】vscode python环境配置
安装python插件:ext install python 配置flake8:pip install flake8 配置yapf:pip install yapf(在VScode中按Alt+Shift ...
- 【scala】2.控制结构和函数
简介 在Java或者C++中,我们把表达式和语句看做两种不同的东西.表达式有值,而语句执行动作. 在Scala中,几乎所有构造出来的语法结构都是有值的.这个特性使得程序更加的精简,也更易读. 1.条件 ...
- BZOJ 2580: [Usaco2012 Jan]Video Game
2580: [Usaco2012 Jan]Video Game Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 142 Solved: 96[Subm ...
- 【BZOJ2724】蒲公英(分块)
[BZOJ2724]蒲公英(分块) 题面 洛谷 谴责权限题的行为 题解 分块什么的都不会,根本就没写过几次. 复杂度根本不会分析,吓得我赶快来练练. 这题要求的是区间众数,显然没有什么很好的主席树之类 ...
- kafka问题集(一):broker少于kafka节点数
问题集仅为个人实践,若有不准确的,欢迎交流! 一.现象: 集群有3台kafka服务器,而kafka 的9002界面上broker仅有2个:log.dirs配置路径为/data/kafka/data,而 ...
- 毕业设计预习:maxplus2入门教程
maxplus2入门教程 一.安装配置(maxplus2.zip) 下载安装完成后,运行maxstart.exe,显示如下错误提示: 为节省配置工作,在E:盘下新建maxplus2文件夹,仅将所需附加 ...