jsonp是跨域请求的手段之一。

jsonp的原理:

先来看看下面这段代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. </head>
  6. <script>
  7. function fn(response){
  8. alert(response);
  9. }
  10. </script>
  11. <body>
  12. </body>
  13. <script src='jsonp.js'></script>//注意这里:jsonp.js 这个js文件中其实只有一句话 fn('响应内容');
  14. </html>

所以原理很简单,其实就是我们定义好了一个方法,然后后台返回一串字符串,而这个字符串又刚好就是一个函数的执行。

  1. fn('响应内容') 这是js文件的内容,本身就是一个函数的执行。

类似:eval("fn('响应内容')");

封装jsonp:

由于ajax不能跨域,所以我们有必要封装一个跨域请求的jsonp方法。

  1. function jsonpAsync(object){
  2. //默认参数
  3. var _object = {
  4. url:"",
  5. jsonp:"",
  6. request:{},
  7. callback:function(respose){}
  8. };
  9.  
  10. //覆盖默认参数
  11. for(var key in object){
  12. _object[key] = object[key];
  13. }
  14. //生成一个唯一的方法名
  15. var fnName = 'jxf_' + new Date().getTime();
  16. //url参数拼接
  17. if(_object.url.indexOf('?') < ){
  18. _object.url += '?';
  19. }
  20. for(var key in _object.request){
  21. if (key != 'jsonp') {
  22. _object.url += '&'+key + '=' + _object.request[key];
  23. };
  24. }
  25. _object.url += '&'+_object.jsonp + '=' + fnName;
  26. //创建script标签
  27. var scriptTag = document.createElement('script');
  28. //将方法注册到全局
  29. window[fnName] = function(response){
  30. try{
  31. _object.callback(response);
  32. }catch(e){
  33. console.log(e);
  34. }finally{
  35. //最后删除该函数与script元素
  36. scriptTag.parentNode.removeChild(scriptTag);
  37. delete window[fnName];//=null
  38. }
  39. }
  40. scriptTag.src = _object.url;
  41. document.getElementsByTagName('head')[].appendChild(scriptTag);
  42. }
  43.  
  44. jsonpAsync({url:'http://localhost:81/jsonp/jsonp.php',jsonp:'jsonp', callback:function(response) {
  45. alert(response.text);
  46. }});

简单点,后台就用php了

  1. <?php
  2. echo $_GET['jsonp']."({text:'响应内容'})";
  3. ?>

Jquery中ajax中的jsonp:

  1. $.ajax({
  2. type : "get",
  3. async: false,
  4. url : "http://localhost:81/jsonp/jsonp.php",
  5. dataType : "jsonp",
  6. jsonp: "jsonp",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名
  7. //jsonpCallback:"zidingyi",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名(类似:jQuery1102016820125747472048_1450147653563({text:'响应内容'}});)
  8. success : function(data){
  9. console.log(data);
  10. },
  11. error:function(){
  12. console.log('fail');
  13. }
  14. });

最后引用一篇比较完成的jsonp的封装:原文链接http://blog.csdn.net/liusaint1992/article/details/50959571

  1. // 主要实现功能:
  2. // 1.参数拼装。
  3. // 2.给每个回调函数唯一命名。
  4. // 3.在回调成功或请求失败之后删除创建的JavaScript标签。 需要兼容IE。IE下onerror事件不兼容。这里有对它的模拟实现。在IE下加载失败也能get到。
  5. // 4.超时功能。超时取消回调。执行error。
  6. // 5.error事件。可执行自己传入的error事件。
  7. function JSONP(url,config){
  8. var data = config.data || [];
  9. var paraArr=[],paraString='';//get请求的参数。
  10. var urlArr;
  11. var callbackName;//每个回调函数一个名字。按时间戳。
  12. var script,head;//要生成script标签。head标签。
  13. var supportLoad;//是否支持 onload。是针对IE的兼容处理。
  14. var onEvent;//onload或onreadystatechange事件。
  15. var timeout = config.timeout || 0;//超时功能。
  16.  
  17. for(var i in data){
  18. if(data.hasOwnProperty(i)){
  19. paraArr.push(encodeURIComponent(i) + "=" +encodeURIComponent(data[i]));
  20. }
  21. }
  22.  
  23. urlArr = url.split("?");//链接中原有的参数。
  24. if(urlArr.length>1){
  25. paraArr.push(urlArr[1]);
  26. }
  27.  
  28. callbackName = 'callback'+new Date().getTime();
  29. paraArr.push('callback='+callbackName);
  30. paraString = paraArr.join("&");
  31. url = urlArr[0] + "?"+ paraString;
  32.  
  33. script = document.createElement("script");
  34. script.loaded = false;//为了实现IE下的onerror做的处理。JSONP的回调函数总是在script的onload事件(IE为onreadystatechange)之前就被调用了。因此我们在正向回调执行之时,为script标签添加一个属性,然后待到onload发生时,再检测有没有这个属性就可以判定是否请求成功,没有成功当然就调用我们的error。
  35.  
  36. //将回调函数添加到全局。
  37. window[callbackName] = function(arg){
  38. var callback = config.callback;
  39. callback(arg);
  40. script.loaded = true;
  41. }
  42.  
  43. head = document.getElementsByTagName("head")[0];
  44. head.insertBefore(script, head.firstChild) //chrome下第二个参数不能为null
  45. script.src = url;
  46.  
  47. supportLoad = "onload" in script;
  48. onEvent = supportLoad ? "onload" : "onreadystatechange";
  49.  
  50. script[onEvent] = function(){
  51.  
  52. if(script.readyState && script.readyState !="loaded"){
  53. return;
  54. }
  55. if(script.readyState == 'loaded' && script.loaded == false){
  56. script.onerror();
  57. return;
  58. }
  59. //删除节点。
  60. (script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));
  61. script = script[onEvent] = script.onerror = window[callbackName] = null;
  62.  
  63. }
  64.  
  65. script.onerror = function(){
  66. if(window[callbackName] == null){
  67. console.log("请求超时,请重试!");
  68. }
  69. config.error && config.error();//如果有专门的error方法的话,就调用。
  70. (script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));
  71. script = script[onEvent] = script.onerror = window[callbackName] = null;
  72. }
  73.  
  74. if(timeout!= 0){
  75. setTimeout(function() {
  76. if(script && script.loaded == false){
  77. window[callbackName] = null;//超时,且未加载结束,注销函数
  78. script.onerror();
  79. }
  80. }, timeout);
  81. }
  82.  
  83. }

html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>jsonp测试</title>
  6. <script src="jsonp.js"></script>
  7. </head>
  8. <body>
  9. <script>
  10. function myerror(){
  11. alert('there must be something wrong!');
  12. }
  13. function getData (data){
  14. alert("服务器过来的数据是"+data);
  15. }
  16. var url = 'http://runningls.com/demos/2016/jsonp/jsonp.php';
  17. //调用函数。
  18. JSONP(url,{
  19. data:{
  20. id:1
  21. },
  22. callback:getData,
  23. error:myerror,
  24. timeout:10000
  25. });
  26. </script>
  27. </body>

php

  1. <?php
  2.  
  3. $callback = $_GET['callback'];
  4. $id = $_GET['id'];
  5.  
  6. if($id == ){
  7. $res = 'this is 1';
  8. }
  9.  
  10. if($id == ){
  11. $res = 'this is 2';
  12. }
  13.  
  14. $res = $callback."('$res')";
  15.  
  16. echo $res;
  17.  
  18. ?>

js跨域请求(jsonp)的更多相关文章

  1. JS跨域请求 JSONP B/S全代码

    Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面.动态网页.web服务.WCF,只要是跨域请求,一律不准:Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有 ...

  2. js跨域请求jsonp解决方案-最简单的小demo

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. js跨域请求方式 ---- JSONP原理解析

    这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下     跨域请求数据解决方案主要有如下解决方法:   1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 H ...

  4. jquery跨域请求jsonp

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

  5. js跨域请求数据的3种常用的方法

    由于js同源策略的影响,当在某一域名下请求其他域名,或者同一域名,不同端口下的url时,就会变成不被允许的跨域请求.那这个时候通常怎么解决呢,对此菜鸟光头我稍作了整理:1.JavaScript   在 ...

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

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

  7. JS跨域:jsonp、跨域资源共享、iframe+window.name

    JS跨域:jsonp.跨域资源共享.iframe+window.name :https://www.cnblogs.com/doudoublog/p/8652213.html JS中的跨域 请求跨域有 ...

  8. 【JS跨域请求】Ajax跨域请求JSONP

    前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资料,原来如此... 为何一直知道jsonp,但一直迷迷糊糊的不明白 ...

  9. JS跨域请求之JSONP

    在项目开发中遇到跨域的问题,一般都是通过JSONP来解决的.但是JSONP到底是个什么东西呢,实现的原理又是什么呢.在项目的空闲时间可以好好的来研究一下了. JSONP的产生 1.众所周知,Ajax请 ...

随机推荐

  1. Codeforces 932 E. Team Work(组合数学)

    http://codeforces.com/contest/932/problem/E 题意:   可以看做 有n种小球,每种小球有无限个,先从中选出x种,再在这x种小球中任选k个小球的方案数 选出的 ...

  2. bzoj千题计划249:bzoj5100: [POI2018]Plan metra

    http://www.lydsy.com/JudgeOnline/problem.php?id=5100 1.找到d1[i]+dn[i] 最小的点,作为1到n链上的点 2.令链长为D,若abs(d1[ ...

  3. AngularJs入门篇-控制器的加深理解基础篇

    下面做的是一个更新时间的效果,每一秒钟就会更新一下,视图中会显示出当前的时间   下面的这个例子中,SceondController函数将接受两个参数,既该DOM元素的$scope和$timeout. ...

  4. Hash::make与Hash::check

    调用方法之前要先去引用: use Illuminate\Support\Facades\Hash; 可以调用 Hash 门面上的 make 方法对存储密码进行哈希: $pwd = Hash::make ...

  5. 爬虫笔记之自如房屋价格图片识别(价格字段css背景图片偏移显示)

    一.前言 自如房屋详情页的价格字段用图片显示,特此破解一下以丰富一下爬虫笔记系列博文集. 二.分析 & 实现 先打开一个房屋详情页观察一下: 网页的源代码中没有直接显示价格字段,价格的显示是使 ...

  6. 【源码阅读】Mimikatz相关资料

    Mimikatz GitHub (源码) https://github.com/gentilkiwi/mimikatz Mimikatz GitHub Wiki (包含了一些说明文档) https:/ ...

  7. linux下常用FTP命令 上传下载文件【转】

    1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密码 ...

  8. vim命令学习

    文本编辑器vim vim常用操作 vim是一个强大的全屏幕文本编辑器,是Linux上最常用的文本编辑器,它的作用是建立,编辑,显示文本文件. vim没有菜单,只有命令. 输入a或i或o进入编辑命令,下 ...

  9. scrapy主动触发关闭爬虫

    在spider中时在方法里直接写 self.crawler.engine.close_spider(self, 'cookie失效关闭爬虫')   在pipeline和downloaderMiddle ...

  10. 解决阿里云安骑士漏洞警告:wordpress WPImageEditorImagick 指令注入漏洞

    解决:wordpress WPImageEditorImagick 指令注入漏洞 前些天在阿里云服务器上安装了wordpress,阿里云提示有wordpress WP_Image_Editor_Ima ...