jQuery的jsonp跨域是这么回事.
实现跨域请求的有iframe,img,script中的src属性.
那么jquery是如何解决跨域请求的呢?
一:
项目jsonp2中有个app.js文件,代码如下:
function app(json){
alert(json['name']);
}
项目jsonp1中的index.html
<script type="text/javascript" src="http://127.0.0.1:8020/jsonp2/js/app.js"></script>
<script type="text/javascript">
app({'name':"guoyansi",'age':25});
</script>
执行结果:
这里的app方法并没有申明,怎么就能调用了呢?
这里的第一个script出现了跨域请求,src指向的是jsonp2中的app.js
而在app.js中申明了app方法.
我们现在在火狐中查看index.html的源码,点开app.js的script

结论:从外部引入的app.js最终会被加载到浏览器中,渲染成这样:
<script type="text/javascript">
function app(json){
alert(json['name']);
}
</script>
根据上面的结论
我们如果利用script跨域向后台发送一个请求,
我们在后端返回一段js代码,前端不就可以调用了吗?
现在我们来验证假设.
我们用java为例子:
新建javaweb项目并且新建一个servlet,
这个servlet返回一个js代码;
package servelt; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class Jsonp2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/javascript;charset=utf-8");//jsonp其实回写的就是一段javascript代码
//或者:response.setContentType("text/plain;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("app({'name':'思思博士','age':'25'})");
out.flush();
out.close();
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
新建另外一个项目并且新建一个index.html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
function app(json){
console.log(json);
}
</script>
<script type="text/javascript" src="http://192.168.6.130:8080/jp/Jsonp2"></script>
</head>
<body> </body>
</html>
上面的第二个script直接执行了这个新的项目上的servlet.
并且最终被浏览器解析成如下格式:
<script type="text/javascript">
app({'name':'思思博士','age':'25'})
</script>
index.html最终的页面变成这个样子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
function app(json){
console.log(json);
}
</script>
<script type="text/javascript">
app({'name':'思思博士','age':'25'})
</script>
</head>
<body> </body>
</html>
上面的代码我想大家都知道是怎么执行的了吧.
上面的代码返回的js代码的方法调用时时在服务器端写死的.我们也可以从客户顿指定要返回的反法调用名.
修改servlet:
package servelt; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class Jsonp2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/javascript;charset=utf-8");//jsonp其实回写的就是一段javascript代码
String appMethod=request.getParameter("appMethod");
PrintWriter out = response.getWriter();
out.print(appMethod+"({'name':'思思博士','age':'25'})");
out.flush();
out.close();
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
在客户端指定要服务器要返回的js方法,添加appMethod参数,修改index.html.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
function app(json){
console.log(json);
}
</script>
<script type="text/javascript" src="http://192.168.6.130:8080/jp/Jsonp2?appMethod=app"></script>
</head>
<body> </body>
</html>
上面的例子都是返回一段可执行的js代码,来调用本地的方法.
我们对上面的例子进行封装.java代码保持不变.
(function($){
$.gys=function(opt){
var scriptCode=(new Date()).getTime();
//拼接script标签
var html="<";
html+="script id='script"+scriptCode+"' type='text/javascript' src='"+opt.src+"?"+opt.callbackName+"="+opt.callback+"'>";
html+="<";
html+"/script>";
//申明一个全局的方法变量供远程返回的js方法的调用,方法名有callback指定
window[opt.callback]=function(json){
opt.success(json);//调用当前参数的方法
$("#script"+scriptCode).remove();//删除script标签
}
$("head").append(html);//插入script标签
}
})(jQuery);
调用:
$(function(){
$.gys({
callbackName:"appMethod",
callback:"app",
src:"http://192.168.6.130:8080/jp/Jsonp2",
success:function(data){
console.log(data);
}
});
});
看到这个有没有觉得和jquery的jsonp有点像了啊.
我们现在看看jquery的jsonp.
jsonp其实用的就是上面的原理
我们看看jquery的jsonp用法.
$.ajax({
type:"get",//jsonp只能触发get请求
url:""//跨域url
dataType:"jsonp",
jsonp:"",//对应上面封装的callbackName
jsonpCallback:"",//对应上面封装的callback
data:{},//提交参数
beforeSend:function(){
//jsonp 方式此方法不被触发。原因是这里已经不是ajax事件了.
},
success:funciton(data){
//参数jsonpCallback的方法调用这里的success
},
error:function(){
//这里不是ajax了,所以这个方法也不会触发.
}
});
jquery中把jsonp和ajax整合在一起了具有一定的迷惑性,ajax是不具有跨域请求的,
另外jsonp使用的核心也不是ajax的xmlhttprequest,而是script的http请求(脚本注入的行为).
另外这样的jsonp是不具有post请求的.
$.getJSON()和$.getScript()都是jsonp的高级封装.
jQuery的jsonp跨域是这么回事.的更多相关文章
- 基于jQuery的Jsonp跨域[Get方式]
由于目前的项目需要无刷新的跨域操作数据,整理了下自己使用的基于jQuery的Jsonp跨域[Get方式]. 代码如下: Javascript部分 $(function(){ $.ajax({ asyn ...
- PHP 支持 JQuery 的 JSONP 跨域访问
Jquery Ajax进行跨域时需要使用JSONP,但JSONP格式和JSON格式是有区别的,如果直接返回JSON格式就会报错 首先将原有的Jquery代码中的dataType改成“jsonp”,具体 ...
- jquery ajax jsonp跨域调用实例代码
今天研究了AJAX使用JSONP进行跨域调用的方法,发现使用GET方式和POST方式都可以进行跨域调用,这里简单分享下,方便需要的朋友 客户端代码 复制代码 代码如下: <%@ Page Lan ...
- 用jQuery实现jsonp跨域
跨域的安全限制都是指浏览器端来说的.服务器端是不存在跨域安全限制的,所以通过本机服务器端通过类似httpclient方式完成“跨域访问”的工作,然后在浏览器端用AJAX获取本机服务器端“跨域访问”对应 ...
- JQuery+ajax+jsonp 跨域访问
Jsonp(JSON with Padding)是资料格式 json 的一种“使用模式”,可以让网页从别的网域获取资料. 关于Jsonp更详细的资料请参考http://baike.baidu.com/ ...
- php+ajax+jquery实现jsonp跨域
我们有这么个html文件test.html: 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...
- jQuery ajax的jsonp跨域请求
一直在听“跨域跨域”,但是什么是跨域呢?今天做了一些了解.(利用jQuery的jsonp) jQuery使用JSONP跨域 JSONP跨域是利用script脚本允许引用不同域下的js实现的,将回调方法 ...
- 33、JSONP跨域
跨域请求数据也是可以的,只不过Ajax这技术不行,而JSONP这种数据格式可以进行跨域.很多年前,浏览器是没有跨域限制的,可以正常跨域,浏览器为了安全和隐私限制了Ajax跨域 JSONP原理就是:将函 ...
- JSONP跨域原理和jQuery.getJSON用法
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式).本文主要介绍JS ...
随机推荐
- 05-Java 集合类详解
(1)Java集合-Collection A.集合可以理解为一个动态的对象数组,不同的是集合中的对象内容可以任意扩充 B.集合特点:性能高,容易扩展和修改 C.Collection的常用子类:List ...
- 根据N种规格中的M种规格值生成的全部规格组合的一种算法
近来在开发SKU模块的时候,遇到这样一个需求,某种商品有N(用未知数N来表示是因为规格的数组由用户制定且随时可以编辑的,所以对程序来说,它是一个未知数)类规格,每一类规格又有M个规格值,各种规格值的组 ...
- android 工程出现感叹号错误
android 工程出现感叹号错误: 错误问题分析,曾经导入的jar已经不存在工程目录中,project从其他地方导入时.没有及时更新,比如说svn下载到.project的文件,或者是path的文件. ...
- jquery中的each方法,$.each \ this.each \ $.fn.each
jquery.each 方法 方法一 $("img").each(function(i,elem){ // i 下标 从零开始, // elem == this // $(elem ...
- css3写出0.5px的边框
一说到0.5px的边框,我们一般认为是不行的,因为在ps中0.5px的线也是做不出来的,这个计算机的像素有关系. 废话不多说了,0.5px 其实用的是css3新特性,box-shadow:阴影设置 代 ...
- 【性能测试】性能测试总结<四>
性能测试常见指标 性能测试说白了就是通过工具模拟多个用户对被测系统进行访问.然后查看系统对于多个用户发来请求的处理能力. 左边的两个小人表示两个用户,向右边服务器发送请求,然后得到服务器 ...
- 面向对象设计模式--策略模式Strategy
策略模式的UML类图(VS2013 C++版本): 策略模式的重点:每个策略对象封装一个算法,有多少个算法就有多少个对象.策略模式的意图是封装算法.要从“抽象不仅面对状态(字段.属性)还面对行为(算法 ...
- C++虚函数和纯虚函数的区别
多态是C++的重要特性,通过基类指针来访问派生类的函数. 虚函数就是为了实现这功能而定义的函数,虚函数可以在定义时实现也可以不实现,定义了虚函数的类可以实例化. 纯虚函数更多的是表示接口的含义,纯虚函 ...
- 拒绝了对对象 '**' (数据库 'db',架构 'dbo')的 SELECT 权限
操作次数据库的用户的权限不够,因此只需要赋予相应的权限即可 MSSQL2005:具体数据库(xxx) --- 安全性---- 架构---- dbo(属性)--- 权限--- 添加--- 浏览-- [p ...
- Mysql触发器简明使用
触发器:trigger创建触发器的语法mysql> delimiter $mysql> create trigger 触发器名称 after/before(触发时间) insert/upd ...