1.在互联网中我们的计算机是通过IP来定位的,但是IP比较难记忆,因此通过domain name(域名)来取代IP

2.什么是跨域?

(1)默认浏览器为了安全问题,禁止了xmlhttprequest跨域访问

(2)<script><iframe><img>等凡是有src属性的标签,默认都是可以访问跨域资源的。

JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。在A域名中不能想访问B域名中的资源,就是跨域。a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。

子域名不相同都算是跨域

3.jquery采用jsonp的方式来解决跨域问题

JSONP : JSON with Padding
1.script标签
2.用script标签加载资源是没有跨域问题的

为什么用script标签可以实现没有跨域呢?

就是因为script标签中的src属性,这个属性有两个作用,第一个可以将指定的资源下载下来,第二个就是不存在跨域问题。

如果指定了script或jsonp类型,那么从服务器接收到数据时,实际是用了<script>标签(get 请求)而不是XMLHttpRequest对象。

在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。

栗子1:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
function fn(data) {
alert(data);
}
</script>
<script src="2.txt"></script>
<script>
//alert(a);
</script>
</head> <body> </body>
</html>

2.txt文件里面的内容是:

fn([1,2,3]);

在资源加载进来之前定义好一个函数function fn(data){alert(data)};,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情
然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,文件里面有fn()函数,这样文件里面的函数就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去

栗子2:

我们希望当点击按钮的时候,再去加载远程资源,让他执行。这个原理就是,动态创建script标签。

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
function fn(data) {
alert(data);
}
</script>
<!--<script src="2.txt"></script>-->
<script>
window.onload = function() { var oBtn = document.getElementById('btn'); oBtn.onclick = function() { //当按钮点击的时候再去加载远程资源,让他执行 var oScript = document.createElement('script');
oScript.src = '2.txt';
document.body.appendChild(oScript); } }
</script>
</head> <body> </body>
</html>

栗子3:

把wampserver服务器开启,把getData.php和这个jsonp跨域.html都放在miaov文件夹下。D:\wamp\www\miaov

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp跨域</title>
<script>
function fn(data){
var oUl1=document.getElementById("ul1");
var html='';
for(var i=0;i<data.length;i++){
html+='<li>'+data[i]+'</li>';
}
oUl1.innerHTML=html;
}
</script>
<script>
window.onload=function(){
var oBtn1=document.getElementById("btn1");
oBtn1.onclick=function(){
var oScript=document.createElement("script");
oScript.src='getData.php';
document.body.appendChild(oScript);
}
}
</script>
</head>
<body>
<input type="button" id="btn1" value="按钮">
<ul id="ul1"></ul>
</body>
</html>

getData.php

<?php

$arr1 = array('11111','222222','333333','4444444','5555');

echo 'fn('.json_encode($arr1).');';

点击加载按钮后页面会这样:

但是,如果不只一个按钮,有多个按钮,不可能还让后端也跟着改变,增加

<?php
$t=isset($_GET['t'])?$_GET['t']:'num';//默认是数字 $arr1 = array('11111','222222','333333','4444444','5555');
$arr2 = array('aaaaaaaaaaaa','bbbbbbbb','cccccccccccc','ddddddddd','eeeeeeeeeeee'); //判断访问的参数,如果是num就输出$arr1,否则$arr2
if($t=='num'){
$data=json_encode($arr1);
}else{
$data=json_encode($arr2);
}
echo 'fn('.$data.');';

这样做是不可取的。

后端可以把接口做好,无论前端做了多少个按钮,只要把参数添加上去就可以访问的到,这样就可以实现动态的变化

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp跨域</title>
<script>
function fn1(data){
var oUl1=document.getElementById("ul1");
var html='';
for(var i=0;i<data.length;i++){
html+='<li>'+data[i]+'</li>';
}
oUl1.innerHTML=html;
} function fn2(data){
var oUl2=document.getElementById("ul2");
var html='';
for(var i=0;i<data.length;i++){
html+='<li>'+data[i]+'</li>';
}
oUl2.innerHTML=html;
} function fn3(data){
var oUl3=document.getElementById("ul3");
var html='';
for(var i=0;i<data.length;i++){
html+='<li>'+data[i]+'</li>';
}
oUl3.innerHTML=html;
}
</script>
<script>
window.onload=function(){
var oBtn1=document.getElementById("btn1");
oBtn1.onclick=function(){
var oScript=document.createElement("script");
oScript.src='getData.php?callback=fn1';
document.body.appendChild(oScript);
} var oBtn2=document.getElementById("btn2");
oBtn2.onclick=function(){
var oScript=document.createElement("script");
oScript.src='getData.php?t=str&callback=fn2';
document.body.appendChild(oScript);
} var oBtn3=document.getElementById("btn3");
oBtn3.onclick=function(){
var oScript=document.createElement("script");
oScript.src='getData.php?callback=fn3';
document.body.appendChild(oScript);
}
}
</script>
</head>
<body>
<input type="button" id="btn1" value="加载数字">
<ul id="ul1"></ul>
<input type="button" id="btn2" value="加载字母">
<ul id="ul2"></ul>
<input type="button" id="btn3" value="加载数字">
<ul id="ul3"></ul>
</body>
</html>

getData.php

<?php
$t=isset($_GET['t'])?$_GET['t']:'num';//默认是数字
$callback=isset($_GET['callback'])?$_GET['callback']:'fn1';//默认是fn1 $arr1 = array('11111','222222','333333','4444444','5555');
$arr2 = array('aaaaaaaaaaaa','bbbbbbbb','cccccccccccc','ddddddddd','eeeeeeeeeeee'); //判断访问的参数,如果是num就输出$arr1,否则$arr2
if($t=='num'){
$data=json_encode($arr1);
}else{
$data=json_encode($arr2);
}
echo $callback.'('.$data.');';

此时callback是函数

实现的效果;

栗子:

同源策略是浏览器的安全基石,但互联网业务往往需要实现跨域通信,以下哪一种方案可以实现跨域?(D)

  A.CSP

  B.AJAX

  C.Oauth

  D.CORS

解释:

同源策略(Same Origin Policy,SOP)是指浏览器请求的资源必须是同域名、同协议、同端口。不同源的客户端脚本(js,actionscript)在没有明确的授权的情况下不能读取对方的资源。
跨源资源(CrossOrigin Resources Sharing,CORS )是一种允许多种资源在一个web页面请求域之外的另一个域的资源的协议,是为了让AJAX能够跨域而生的。
内容安全策略(Content Security Policy,CSP)是一种白名单机制,限制网站中是否可以包含某来源的内容。
Oauth是一个关于授权的开放网络标准,相当于在客户端与服务器之间添加了一个授权层。
 

比如,有个a.html页面,它里面的代码需要利用ajax获取一个不同域上的json数据,假设这个json数据地址是http://example.com/data.php,那么a.html中的代码就可以这样:

通过http://example.com/data.php?callback=dosomething得到的js文件,就是我们之前定义的dosomething函数,并且它的参数就是我们需要的json数据,这样我们就跨域获得了我们需要的数据。

这样jsonp的原理就很清楚了,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。

http://example.com/data.php这个文件是这样的

最终输出的结果是:

知道jsonp跨域的原理后我们就可以用js动态生成script标签来进行跨域操作了,而不用特意的手动的书写那些script标签。如果你的页面使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了。

原理是一样的,只不过我们不需要手动的插入script标签以及定义回调函数。jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

本文主要根据http://www.cnblogs.com/2050/p/3191744.html

jquery跨域解决方案JSONP的更多相关文章

  1. 前端跨域解决方案: JSONP的通俗解说和实践

     对于前端开发者而言,跨域是一个绕不开的话题.只有真正明白了各种方案的工作机制,才能针对性地进行跨域方案选型.本文将以探索者的视角,试图用最通俗的语言对一种"鼎鼎大名"的跨域解决方 ...

  2. 彻底理解跨域解决方案JSONP

    什么是同源策略? 同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略. 所谓同源是指,域名,协议,端口相同.当一个浏览器的两个tab页 ...

  3. jquery跨域请求jsonp

    服务端PHP代码  header('Content-Type:application/json; charset=utf-8'); $arr = array('a'=>1, 'b'=>2, ...

  4. 跨域解决方案 - JSONP

    目录 1. 定义 2. JSONP 解决跨域 3. 应用场景 4. 代码演示 1. 定义 在HTML 中, script 标签有两个个性质: script 标签可以不受同源策略的限制去访问服务器资源, ...

  5. jquery跨域调用wcf

    使用jquery跨域调用wcf服务的时候会报如下错误 $.ajax({ url: 'http://localhost:28207/Service1.svc/GetData', method: 'get ...

  6. 浏览器同源策略,跨域请求jsonp

    浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...

  7. jquery跨域访问解决方案(转)

    客户端“跨域访问”一直是一个头疼的问题,好在有jQuery帮忙,从jQuery-1.2以后跨域问题便迎刃而解.由于自己在项目中遇到跨域问题,借此机会对跨域问题来刨根问底,查阅了相关资料和自己的实践,算 ...

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

    加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回 ...

  9. Jquery跨域请求php数据(jsonp)

    Jquery跨域请求php数据 我们一般用到ajax的时候是在同服务器下,一般情况下不会跨域,但有时候需要调用其他域名或ip下的数据的时候,遇到跨域请求数据的时候. 今天在工作中碰到javascrip ...

随机推荐

  1. C#多线程Thread

    在项目中经常用到线程Thread,先做个简单记录,后面再完善下,方便以后参考.本人技术有限,如有不同见解之处,欢迎博友批评指正. 执行的线程Thread分无参数的,一个参数,多个参数的.直接看代码吧. ...

  2. Spark job执行流程消息图

    Spark job执行流程消息图 1.介绍

  3. vos套餐设置

    为实现对客户不同时段按不同费率计算,可以在vos里设置套餐, 具体案例: 1. 2.时段费率 套餐里没包含的时间段是不能打电话的 即:周一到周五       21:30—24:00    00:00- ...

  4. hp zbook15G2 nVidia K1100M显卡在ubuntu linux下闪屏问题

    我的hp zbook15G2有一块nVidia K1100M显卡. 故障现象 安装ubuntu 16.4之后,屏幕出现闪烁现象. 重启后,进入bios,屏幕依然在闪烁. 再重启,进入另一块硬盘的win ...

  5. PHP设计模式练习——制作简单的投诉页面

    ---恢复内容开始--- <?php /* * 设计模式练习 * 1.数据库连接类(单例模式) * 2.调用接口实现留言本功能(工厂模式) * 3.实现分级举报处理功能(责任链模式) * 4.发 ...

  6. linux awk 内置函数详细介绍(实例)

    这节详细介绍awk内置函数,主要分以下3种类似:算数函数.字符串函数.其它一般函数.时间函数 一.算术函数: 以下算术函数执行与 C 语言中名称相同的子例程相同的操作: 函数名 说明 atan2( y ...

  7. sql插入临时表数据的方法

    方法有两种,主要看需求. 方法1:定义好临时表的字段和类型.插入对应的值 create table #Tmp --创建临时表#Tmp ( City varchar(), -- Country varc ...

  8. HttpServerUtility 和 HttpUyility

    参考:msdn HttpServerUtility 提供用于处理 Web 请求的 Helper 方法. 2017/08/07            加密解码 这个类没有构造函数,所以不能直接new. ...

  9. 用dockers实现mysql主从同步

    首先要先看看当前的mysql的版本是什么,可以通过下面命令查看 mysql --version 最好是安装在docker中的mysql和你宿主机器中的mysql版本一致. 我的是mysql5.7.22 ...

  10. JT796、JT1077部标平台检测报名须知

    检测报名须知 申请道路运输车辆卫星定位系统平台标准符合性检测时,请先将1检测意向单(只针对企业监控平台).2符合性检测申请材料(基本材料包括:申请函.授权人身份证复印件.检测登记表.运输企业信息表.平 ...