前两天被问到ajax跨域怎样解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来。抱着有问题必须解决的态度,我看了很多资料,原来如此。。

为何一直知道jsonp,但一直迷迷糊糊的不明确呢?——网上那些介绍资料都写的太复杂了!

我是能多简单就多简单,争取让你十分钟看完!

1. 同源策略

ajax之所以须要“跨域”。罪魁祸首就是浏览器的同源策略。即,一个页面的ajax仅仅能获取这个页面同样源或者同样域的数据。

怎样叫“同源”或者“同域”呢?——协议、域名、port号都必须同样。比如:

http://google.com  和  https://google.com 不同。由于协议不同;

http://localhost:8080  和  http://localhost:1000 不同。由于port不同。

http://localhost:8080  和  https://google.com 不同,协议、域名、port号都不同,根本不是一家的。

依据同源策略,我自己做的一个网页 http://localhost:8080/test.html 就无法通过ajax直接获取 http://google.com 的数据。

比如,我用ajax去訪问一个不同域的页面。错误结果是这种:

大家想想。这样事实上也有道理。假设没有同源策略,你我都能够随便通过ajax直接获取其它站点的信息,这还不乱套了。

。。我自己做一个搜索界面,搜索时直接用ajax从百度获取数据,那不成了小偷了。

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

2. 从“盗链”说起

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

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

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

重点:<img>的src(获取图片),<link>的href(获取css)。<script>的src(获取javascript)这三个都不符合同源策略。它们能够跨域获取数据。

因此,你能够直接从一些cdn上获取jQuery。而且你站点上的图片也随时可能被别人盗用,全部最好加上水印!

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

3. 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 编写例如以下代码:

<script type='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>
function myFn ( data ) {
alert( data + 'px' );
}
</script>
<script type='text/javascript' src='http://b.com/alert.js'/>

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

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

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

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

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

引导第四步:引用html格式

<script>的src不一定只指向javascript文件,能够指向不论什么地址。

比如:

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

<script>
function myFn ( data ) {
alert( data + 'px' );
}
</script>
<script type='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>
function myFn ( data ) {
alert( data + 'px' );
}
</script>
<script type='text/javascript' src='http://b.com/data.aspx?callback=myFn'/>

大家注意,我们在 src 地址中添加了“?

callback=myFn”,意思是把显示数据的函数也动态传过去了,而第二步、第四步都是静态的写在被调用的文件里的。

至于callback參数后台怎样接收。怎样使用,请接着看:

在 b.com 下添加一个 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"]; //server端要返回的数据
string data = "1024"; Response.Write(callback + "(" + data + ")");
}
}
}

代码非常easy。获取callback參数,然后组成一个函数的形式返回。假设“b.com/data.aspx?

callback=myFn”调用的话,那么返回的就是" myFn(1024) "。

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

引导第六步:调用封装

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

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

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

4. 总结

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

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

ok,就这些!

-------------------------------------------------------------------------------------------------------------

欢迎关注我的微博

也欢迎关注我的其它教程:

从设计到模式》《深入理解javascript原型和闭包系列》《微软petshop4.0源代码解读视频》《json2.js源代码解读视频

js便签笔记(13)——jsonp事实上非常easy【ajax跨域请求】的更多相关文章

  1. js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2

    1. 前言 昨天写了<js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1>,简单记录了几个问题.part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭 ...

  2. js便签笔记(2)——DOM元素的特性(Attribute)和属性(Property)

    1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...

  3. jsonp其实很简单【ajax跨域请求】

    js便签笔记(13)——jsonp其实很简单[ajax跨域请求] 前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资 ...

  4. ajax跨域请求学习笔记

    原文:ajax跨域请求学习笔记 前言 ajax,用苍白的话赞扬:很好. 我们可以使用ajax实现异步获取数据,减少服务器运算时间,大大地改善用户体验:我们可以使用ajax实现小系统组合大系统:我们还可 ...

  5. JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

    1. 学习计划 第十一天: 1.sso注册功能实现 2.sso登录功能实现 3.通过token获得用户信息 4.Ajax跨域请求(jsonp) 2. Sso系统工程搭建 需要创建一个sso服务工程,可 ...

  6. 为什么返回的数据前面有callback? ashx/json.ashx?的后面加 callback=? 起什么作用 js url?callback=xxx xxx的介绍 ajax 跨域请求时url参数添加callback=?会实现跨域问题

    为什么返回的数据前面有callback?   这是一个同学出现的问题,问到了我. 应该是这样的: 但问题是这样的: 我看了所请求的格式和后台要求的也是相同的.而且我也是这种做法,为什么他的就不行呢? ...

  7. JSONP实现Ajax跨域请求

    前言 由于浏览器存在同源策略的机制,所谓同源策略就是阻止从一个源(域名,包括同一个根域名下的不同二级域名)加载的文档或者脚本获取/或者设置另一个源加载的文档属性. 但比较特别的是:由于同源策略是浏览器 ...

  8. NodeJ node.js Jquery Ajax 跨域请求

    Jquery + Ajax 跨域请求 说白了就是前台请求ajax数据(JSON)但是请求的数据不在本地的绝对路径下,接口数据 是没有这个安全性的我对外公开的接口数据,只要你找到接口你就可以使用里面的数 ...

  9. 利用jsonp进行Ajax跨域请求

    在进行Ajax请求的时候经常会遇到跨域的问题,这个时候一般就会用到jsonp. 关于json和jsonp,网上有很多原理解释,这里就不多赘述,需要的自行搜索. 下面是一个简单的ajax跨域请求示例: ...

随机推荐

  1. 左右mysql事务提交

    package com.itheima.trans; import java.sql.Connection; import java.sql.PreparedStatement; import jav ...

  2. (九)通过几段代码,理清angularJS中的$injector、$rootScope和$scope的概念和关联关系

    $injector.$rootScope和$scope是angularJS框架中比較重要的东西,理清它们之间的关系,对我们兴许学习和理解angularJS框架都很实用. 1.$injector事实上是 ...

  3. Android 之流媒体播放器,广播侧下方这么简单。

    没有其他的.希望从事流媒体开发案例.还承诺提供朋友博客.上个星期.制定出最后一点机会. 在这里,与大家分享. 首先要明白的概念:什么是流媒体?转载请注明出处http://blog.csdn.net/g ...

  4. 使用JavaMail发送和接收电子邮件

    一. 为什么要学习JavaMail 为什么要学习JavaMail开发? 如今非常多WEB应用在开发时都须要集成邮件发送功能.比如: 1. 给新注冊的用户自己主动发送一封包括其注冊信息的欢迎E-Mail ...

  5. cisco(思科)交换机配置篇【两】

    上一页大家津津乐道cisco基本操作命令开关,而端午假期,该cisco简单的开关配置,并希望请您分享"端午节快乐"!Ok,配置交换机,首先,你必须进入全局配置模式Switch,在成 ...

  6. 编辑简单的 shell程序

    编辑简单的 shell程序 知道了vi编辑器的使用规则之后,结合shell的使用规则,可以编辑简单的 shell程序试试手 题目如下: 1.用while语句创建一个根据输入的数值求累加和(1+2+3+ ...

  7. 使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表

    原文:使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表 我们知道目标平台是32位的程序运行在64位的系统上,去访问部分注册表的时候系统自动重定向到win32node节点对应的 ...

  8. WPF命令參数CommandParameter

    XAML代码例如以下: <Window x:Class="Demo006.MainWindow" xmlns="http://schemas.microsoft.c ...

  9. 源码安装apache及配置转发

    一.    安装Apache a)    解压:tar -xvf httpd-*; b)    ./configure --prefix=/usr/oracle/apache CC="gcc ...

  10. ADO.NET连接方式

    使用Command.DataReader和DataSet两种方法实现数据绑定 方法1:使用Command和DataReader SqlConnection con = new SqlConnectio ...