js跨域请求(jsonp)
jsonp是跨域请求的手段之一。
jsonp的原理:
先来看看下面这段代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<script>
function fn(response){
alert(response);
}
</script>
<body>
</body>
<script src='jsonp.js'></script>//注意这里:jsonp.js 这个js文件中其实只有一句话 fn('响应内容');
</html>
所以原理很简单,其实就是我们定义好了一个方法,然后后台返回一串字符串,而这个字符串又刚好就是一个函数的执行。
(
fn('响应内容') 这是js文件的内容,本身就是一个函数的执行。
)
类似:eval("fn('响应内容')");
封装jsonp:
由于ajax不能跨域,所以我们有必要封装一个跨域请求的jsonp方法。
function jsonpAsync(object){
//默认参数
var _object = {
url:"",
jsonp:"",
request:{},
callback:function(respose){}
};
//覆盖默认参数
for(var key in object){
_object[key] = object[key];
}
//生成一个唯一的方法名
var fnName = 'jxf_' + new Date().getTime();
//url参数拼接
if(_object.url.indexOf('?') < ){
_object.url += '?';
}
for(var key in _object.request){
if (key != 'jsonp') {
_object.url += '&'+key + '=' + _object.request[key];
};
}
_object.url += '&'+_object.jsonp + '=' + fnName;
//创建script标签
var scriptTag = document.createElement('script');
//将方法注册到全局
window[fnName] = function(response){
try{
_object.callback(response);
}catch(e){
console.log(e);
}finally{
//最后删除该函数与script元素
scriptTag.parentNode.removeChild(scriptTag);
delete window[fnName];//=null
}
}
scriptTag.src = _object.url;
document.getElementsByTagName('head')[].appendChild(scriptTag);
}
jsonpAsync({url:'http://localhost:81/jsonp/jsonp.php',jsonp:'jsonp', callback:function(response) {
alert(response.text);
}});
简单点,后台就用php了
<?php
echo $_GET['jsonp']."({text:'响应内容'})";
?>


Jquery中ajax中的jsonp:
$.ajax({
type : "get",
async: false,
url : "http://localhost:81/jsonp/jsonp.php",
dataType : "jsonp",
jsonp: "jsonp",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名
//jsonpCallback:"zidingyi",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名(类似:jQuery1102016820125747472048_1450147653563({text:'响应内容'}});)
success : function(data){
console.log(data);
},
error:function(){
console.log('fail');
}
});
最后引用一篇比较完成的jsonp的封装:原文链接http://blog.csdn.net/liusaint1992/article/details/50959571
// 主要实现功能:
// 1.参数拼装。
// 2.给每个回调函数唯一命名。
// 3.在回调成功或请求失败之后删除创建的JavaScript标签。 需要兼容IE。IE下onerror事件不兼容。这里有对它的模拟实现。在IE下加载失败也能get到。
// 4.超时功能。超时取消回调。执行error。
// 5.error事件。可执行自己传入的error事件。
function JSONP(url,config){
var data = config.data || [];
var paraArr=[],paraString='';//get请求的参数。
var urlArr;
var callbackName;//每个回调函数一个名字。按时间戳。
var script,head;//要生成script标签。head标签。
var supportLoad;//是否支持 onload。是针对IE的兼容处理。
var onEvent;//onload或onreadystatechange事件。
var timeout = config.timeout || 0;//超时功能。 for(var i in data){
if(data.hasOwnProperty(i)){
paraArr.push(encodeURIComponent(i) + "=" +encodeURIComponent(data[i]));
}
} urlArr = url.split("?");//链接中原有的参数。
if(urlArr.length>1){
paraArr.push(urlArr[1]);
} callbackName = 'callback'+new Date().getTime();
paraArr.push('callback='+callbackName);
paraString = paraArr.join("&");
url = urlArr[0] + "?"+ paraString; script = document.createElement("script");
script.loaded = false;//为了实现IE下的onerror做的处理。JSONP的回调函数总是在script的onload事件(IE为onreadystatechange)之前就被调用了。因此我们在正向回调执行之时,为script标签添加一个属性,然后待到onload发生时,再检测有没有这个属性就可以判定是否请求成功,没有成功当然就调用我们的error。 //将回调函数添加到全局。
window[callbackName] = function(arg){
var callback = config.callback;
callback(arg);
script.loaded = true;
} head = document.getElementsByTagName("head")[0];
head.insertBefore(script, head.firstChild) //chrome下第二个参数不能为null
script.src = url; supportLoad = "onload" in script;
onEvent = supportLoad ? "onload" : "onreadystatechange"; script[onEvent] = function(){ if(script.readyState && script.readyState !="loaded"){
return;
}
if(script.readyState == 'loaded' && script.loaded == false){
script.onerror();
return;
}
//删除节点。
(script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));
script = script[onEvent] = script.onerror = window[callbackName] = null; } script.onerror = function(){
if(window[callbackName] == null){
console.log("请求超时,请重试!");
}
config.error && config.error();//如果有专门的error方法的话,就调用。
(script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));
script = script[onEvent] = script.onerror = window[callbackName] = null;
} if(timeout!= 0){
setTimeout(function() {
if(script && script.loaded == false){
window[callbackName] = null;//超时,且未加载结束,注销函数
script.onerror();
}
}, timeout);
} }
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jsonp测试</title>
<script src="jsonp.js"></script>
</head>
<body>
<script>
function myerror(){
alert('there must be something wrong!');
}
function getData (data){
alert("服务器过来的数据是"+data);
}
var url = 'http://runningls.com/demos/2016/jsonp/jsonp.php';
//调用函数。
JSONP(url,{
data:{
id:1
},
callback:getData,
error:myerror,
timeout:10000
});
</script>
</body>
php
<?php $callback = $_GET['callback'];
$id = $_GET['id']; if($id == ){
$res = 'this is 1';
} if($id == ){
$res = 'this is 2';
} $res = $callback."('$res')"; echo $res; ?>
js跨域请求(jsonp)的更多相关文章
- JS跨域请求 JSONP B/S全代码
Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面.动态网页.web服务.WCF,只要是跨域请求,一律不准:Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有 ...
- js跨域请求jsonp解决方案-最简单的小demo
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- js跨域请求方式 ---- JSONP原理解析
这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 H ...
- jquery跨域请求jsonp
服务端PHP代码 header('Content-Type:application/json; charset=utf-8'); $arr = array('a'=>1, 'b'=>2, ...
- js跨域请求数据的3种常用的方法
由于js同源策略的影响,当在某一域名下请求其他域名,或者同一域名,不同端口下的url时,就会变成不被允许的跨域请求.那这个时候通常怎么解决呢,对此菜鸟光头我稍作了整理:1.JavaScript 在 ...
- 浏览器同源策略,跨域请求jsonp
浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...
- JS跨域:jsonp、跨域资源共享、iframe+window.name
JS跨域:jsonp.跨域资源共享.iframe+window.name :https://www.cnblogs.com/doudoublog/p/8652213.html JS中的跨域 请求跨域有 ...
- 【JS跨域请求】Ajax跨域请求JSONP
前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资料,原来如此... 为何一直知道jsonp,但一直迷迷糊糊的不明白 ...
- JS跨域请求之JSONP
在项目开发中遇到跨域的问题,一般都是通过JSONP来解决的.但是JSONP到底是个什么东西呢,实现的原理又是什么呢.在项目的空闲时间可以好好的来研究一下了. JSONP的产生 1.众所周知,Ajax请 ...
随机推荐
- python---django中orm的使用(3)admin配置与使用
新建项目,并开启 python manage.py runserver 访问admin页面 http://127.0.0.1:8080/admin 补充:若是发现admin页面样式丢失:可能是因为在s ...
- ActiveMQ基础教程JMS概述
什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息 ...
- disabled属性对form表单向后台传值的影响
在form表单里,如果对input加入disabled="disabled"或disabled="true"等属性,form表单提交的时候,就不会传值到后台. ...
- POJ 2965 The Pilots Brothers' refrigerator (暴力枚举)
https://vjudge.net/problem/POJ-2965 与poj-1753相似,只不过这个要记录路径.poj-1753:https://www.cnblogs.com/fht-lito ...
- 那些年的 网络通信之 TCP/IP 传输控制协议 ip 加 端口 客户端上传文件到服务器端服务器端返回上传成功消息
多线程开启, 客户端通过 Socket 流 上传文件到服务端的一个小程序练习. 1. 抓住阻塞式方法,去调试 2. 获取对应流对象操作对应的对象 这时候自己不能懵,一定要清晰,最好命名就能区别,一搞混 ...
- 基于序列化技术(Protobuf)的socket文件传输
好像好久都没更博文了,没办法,最近各种倒霉事情,搞到最近真的没什么心情,希望之后能够转运吧. 言归正传,这次我要做的是基于序列化技术的socket文件传输来无聊练一下手. 一.socket文件传输 之 ...
- nmap - 网络扫描
NMap,Network Mapper 最早是Linux下的网络扫描和嗅探工具包 网络链接扫描; nmap -PT 192.168.1.1-111 # 先ping在扫描主机开放端口 nmap -O 1 ...
- str函数
python2: a = str(unicode类对象) #str()函数如果接收的参数是unicode类,会转换为python的defaultencoding格式,所以,如果unicode类对象是汉 ...
- mysql学习------错误日志和通用查询日志
一.启动错误日志 1.在不同情况下,错误日志会记录在不同的位置.如果没有在配置文件中指定文件名,则文件名默认为hostname.err 2.在mysql5.6的rpm发布方式中,错误的日志默认的放置在 ...
- 拓展中国剩余定理(exCRT)摘要
清除一个误区 虽然中国剩余定理和拓展中国剩余定理只差两个字,但他俩的解法相差十万八千里,所以会不会CRT无所谓 用途 求类似$$\begin{cases}x \equiv b_{1}\pmod{a_{ ...