同源策略

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从百度获取数据,那不成了小偷了。。。

但是跨域访问是少不了的,mail.163.com 的网页可能需要从 news.163.com 域下获取新闻信息,那怎么办?——开始咱们的跨域之旅。(当然用iframe也可以实现)

从“盗链”说起

互联网的许多网站之间图片相互盗链,A网站网页的img.src直接链接到B网站的图片地址,这是常有的事儿。说到“盗链”,大家第一想到的可能是如何去防止盗链,今儿咱不管那个。

你再想想“盗链”和“同源策略”这两个词之间有什么关系?——对,矛盾!既然都“同源策略”了,怎么还能“盗链”呢?

世间万物都有矛盾,有矛盾了照样可以和谐共处,并不一定非要你死我活。

重点:<img>src(获取图片),<link>href(获取css),<script>src(获取javascript)这三个都不符合同源策略,它们可以跨域获取数据。因此,你可以直接从一些cdn上获取jQuery,并且你网站上的图片也随时可能被别人盗用,所有最好加上水印!

而我们今天的主角——jsonp——就是因为<script>的src不符合同源策略而来的。

JSONP

例如,域名 a.com 下有一个 a.com/test.html 网页,域名 b.com 下有一个 b.com/data.html 网页和 b.com/alert.js 文件。

引导第一步:简单引用js

编写 b.com/alert.js 如下:

alert(123);

对 a.com/test.html 编写如下代码:

<scripttype='text/javascript'src='http://b.com/alert.js'/>

运行 a.com/test.html,结果很明显,就是弹出123

引导第二步:引用js返回数据

将 b.com/alert.js 修改为:

myFn(100);

将 a.com/test.html 修改为:

<script>functionmyFn (data ){alert(data +'px');}</script><scripttype='text/javascript'src='http://b.com/alert.js'/>

运行 a.com/test.html,结果是弹出100px,这个应该也没有什么疑问。

引导第三步:已经跨域成功!

第二步中,如果data——即100——是我要跨域在b.com下获取的一个数据,那么咱们这不就是已经实现跨域请求了吗!!!

把这个过程再清晰的捋一遍:

  • <script>src不符合同源策略;
  • 我通过给<script>src赋值一个跨域的文件的网址(可能不是一个js文件),这个文件返回的字符串,浏览器会当作javascript来解析;
  • 而这段javascript中,就可以包含着我所需要的跨域服务器端的数据;
  • 最后,我在本页面定义一个myFn函数用来展示数据,而这段javascript中就可以直接调用myFn函数;

引导第四步:引用html格式

<script>src不一定仅仅指向javascript文件,可以指向任何地址。例如:
将 a.com/test.html 修改为:

<script>functionmyFn (data ){alert(data +'px');}</script><scripttype='text/javascript'src='http://b.com/data.html'/>

将 b.com/data.html 编写为:(注意,data.html中就写以下一行代码,多了不写)

myFn(100);

运行 a.com/test.html ,结果依然是100px,其中,100就是我们要跨域请求的数据。

引导第五步:动态数据

如果要请求的数据是动态的,那就要在动态页面中编写。那么我们就让 a.com/test.html 去调用一个动态的aspx页面:

<script>functionmyFn (data ){alert(data +'px');}</script><scripttype='text/javascript'src='http://b.com/data.aspx?callback=myFn'/>

大家注意,我们在 src 地址中增加了?callback=myFn,意思是把显示数据的函数也动态传过去了,而第二步、第四步都是静态的写在被调用的文件中的。至于callback参数后台如何接收,如何使用,请接着看:
在 b.com 下增加一个 b.com/data.aspx 页面,后台代码如下:

protectedvoidPage_Load(objectsender,EventArgse){if(this.IsPostBack==false){stringcallback ="";if(Request["callback"]!=null){callback =Request["callback"];//服务器端要返回的数据stringdata ="1024";Response.Write(callback +"("+data +")");}}}

代码很简单,获取callback参数,然后组成一个函数的形式返回。如果b.com/data.aspx?callback=myFn调用的话,那么返回的就是myFn(1024)

返回的数据变成动态的了(“1024”),前端页面用于显示数据的函数也编程了动态的了(“callback=myFn”),但是归根结底,形式还是一样的。

引导第六步:调用封装

a.com/test.html 中,仅仅有一个<script>静静的躺在那里,执行一次之后,就没有作用了。

而实际情况是,a.com/test.html 中,可能随着用户的操作发生若干次的调用。怎么办?——动态增加呗。

functionaddScriptTag(src){varscript =document.createElement("script");script.setAttribute("type","text/javascript");script.src =src;document.body.appendChild(script);}functionmyFn (data){alert(data +'px');}//需要调用时://addScriptTag('b.com/data.aspx?callback=myFn');

总结

以上层层描述的就是JSONP,你不必去记住它的定义,看明白了上述文字,就全能理解。

重点在于:同源策略 + <script>src不属于同源策略 + 通过<script>的src指向的文件返回服务器端数据。

ok,就这些!

转载于:https://www.cnblogs.com/gopark/p/8157295.html

JSONP - 从理论到实践相关推荐

  1. ARM NEON指令集优化理论与实践

    ARM NEON指令集优化理论与实践 一.简介 NEON就是一种基于SIMD思想的ARM技术,相比于ARMv6或之前的架构,NEON结合了64-bit和128-bit的SIMD指令集,提供128-bi ...

  2. CPU消耗,跟踪定位理论与实践

    CPU消耗,跟踪定位理论与实践 一.性能指标之资源指标定位方案 1.打tprof报告方法 抓取perfpmr文件 60秒. perfpmr.sh 60 从结果文件中取出tprof.sum 或直接抓取t ...

  3. UI设计培训之如何将设计理论与实践相结合

    学习UI设计理论知识与实践技术都是要有的,很多人都不爱去听理论知识,这对以后的工作是没有任何帮助的,只有将设计理论与实践相结合才能帮助到自己,那么如何将设计理论与实践相结合?来看看本期下面的详细介绍. ...

  4. Java 理论与实践: 非阻塞算法简介——看吧,没有锁定!(转载)

    简介: Java™ 5.0 第一次让使用 Java 语言开发非阻塞算法成为可能,java.util.concurrent 包充分地利用了这个功能.非阻塞算法属于并发算法,它们可以安全地派生它们的线程, ...

  5. Microsoft NLayerApp案例理论与实践 - 项目简“.NET研究”介与环境搭建

    项目简介 Microsoft – Spain团队有一个很不错的面向领域多层分布式项目案例:Microsoft – Domain Oriented N-Layered .NET 4.0 App Samp ...

  6. 重磅直播|立体视觉之立体匹配理论与实践​

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 大家好,本公众号现已开启线上视频公开课,主讲人通过B站直播间,对3D视觉领域相关知识点进行讲解,并在微 ...

  7. java 理论与实践,Java 理论与实践: 正确使用 Volatile 变量

    Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低) ...

  8. 干货 | 清华大学郑方:语音技术用于身份认证的理论与实践

    本讲座选自清华大学语音和语言技术中心主任郑方教授近期于清华大数据"技术·前沿"系列讲座上所做的题为<语音技术用于身份认证的理论与实践>的演讲. 以下为演讲的主要内容: ...

  9. WAIC 2021 | 百度量子计算段润尧:从理论到实践谈量子人工智能

    在 WAIC 2021 AI 开发者论坛上,百度研究院量子计算研究所所长段润尧发表主题演讲<量子人工智能:从理论到实践>.在演讲中,段润尧讲述了量子计算的理论基础,对量子人工智能的发展现状 ...

  10. Java 理论与实践: 流行的原子——新原子类是 java.util.concurrent 的隐藏精华(转载)...

    简介: 在 JDK 5.0 之前,如果不使用本机代码,就不能用 Java 语言编写无等待.无锁定的算法.在 java.util.concurrent 中添加原子变量类之后,这种情况发生了变化.请跟随并 ...

最新文章

  1. muduo网络库学习(八)事件驱动循环线程池EventLoopThreadPool
  2. 第29课 布纳特老师出的难题 《小学生C++趣味编程》
  3. LCA问题的RMQ解法解析
  4. 初学iBATIS的朋友,如果你不看我这篇文章,你一定后悔,因为它官方文档里面的示例少一个
  5. 初识openwrt(下)
  6. Feature Scaling(特征缩放)的一些方法和使用选择
  7. 「Django」contenttypes基本用法
  8. 【Linux 应用编程】进程管理 - 进程、线程和程序
  9. WPS制作甘特图实操(带图超详细)
  10. 【第63期】机器人时代已来!推荐几本机器人学硬核好书
  11. vision画流程图的软件_流程图制作软件visio|流程图制作软件visio vs2010 中文版 - 软件下载 - 绿茶软件园|33LC.com...
  12. 【前端GUI】—— 网站美工必须掌握的PS知识点思维导图
  13. 私服架设教程-菜鸟篇
  14. 高等数学学习笔记——第六十讲——向量值函数的导数与积分
  15. 「津津乐道播客」#273 科技乱炖:实时音频社交爆红的冷思考
  16. 为什么那么多的人选择到Java培训机构学习
  17. LeetCode 164. 最大间距(桶排序+鸽笼原理)
  18. 中国石油大学《机械电气安全技术(含课程设计)》第三阶段在线作业
  19. 2015年中国视频监控市场发展特点及未来展望
  20. OCA全贴合材料工艺解析

热门文章

  1. linux孟庆昌第六章课后题_周三多管理学第5版课后答案资料笔记和课后习题含考研真题详解...
  2. oracle里的or 短路么,Oracle CASE短路不能分组工作
  3. 重写需要注意哪些方面?
  4. python爬虫爬取网页图片_Python之多线程爬虫抓取网页图片
  5. Hyperledger Fabric教程(1)--Hyperledger Fabric 老版本 1.1.0 快速部署安装
  6. github API 实例 python源码 爬取用户信息
  7. SpringBoot启动o.s.b.d.LoggingFailure… 错误解决方法
  8. c语言中ox1小于小于a,丹江口市2018适应性数学试卷和答案
  9. 二维数组代表迷宫java_Java 二维数组迷宫游戏
  10. 十七、Oracle学习笔记:视图操作和表复制