JSONP

能长久的存放数据就是数据库!

  if(path === '/'){
    var string = fs.readFileSync('./index.html','utf8')
    var amount = fs.readFileSync('./db','utf8')//同步读一个文件
    string=string.replace('&&&amount&&&',amount)
    可以用&&&amount&&&在HTML中当占位符,后端处理数据的时候替换掉这个占位符就行了
    response.setHeader('Content-Type', 'text/html; charset=utf-8')
    返回的也是一个页面 必须要设置好页面格式
    response.write(string)
    response.end()
  }else if( path === '/style.css'){
    var string = fs.readFileSync('./style.css','utf8')
    response.setHeader('Content-Type', 'text/css')
    response.write(string)
    response.end()
  }else if( path === '/main.js'){
    var string = fs.readFileSync('./main.js','utf8')
    response.setHeader('Content-Type', 'application/javascript')
    response.write(string)
    response.end()
  }else if(path === '/pay' && method.toUpperCase()==='POST'){
     var amount = fs.readFileSync('./db','utf8')//同步读一个文件
     var newAmount = amount - 1
     fs.writeFileSync('./db',newAmount)
     response.write('success!')
     response.end()
  }
  else{
    response.statusCode = 404
    response.setHeader('Content-type','text/html;charset=utf-8')
    response.write('找不到对应的路径')
    response.end()
  } 

html页面用form表单提交一个post请求,服务器改变数据再返回刷新到页面
一开始是用iframe在页面上显示改变数据,太古老,已经被众人忘记

想到用img创建请求 但是只能创建get请求
浏览器一旦发现img标签,就会发送一个请求,就是img的src

 let img = document.createElement('img')
      img.src = '/pay'
      img.onload = function () {
        alert('success')
        window.location.reload() //页面刷新
      }
      img.onerror = function () {
        alert('false')
      }

var amount = fs.readFileSync('./db','utf8')//同步读一个文件
     var newAmount = amount - 1
     if(Math.random()>0.5){
       fs.writeFileSync('./db', newAmount)
       response.setHeader('Content-Type','image/jpg')
       response.statusCode = 200
       response.write(fs.readFileSync('./1.jpg'))
     }
     else{
       response.statusCode = 400
       response.write('fail')
     }
     response.end()

onload加载成功 onerror 加载失败 因为假的图片骗不了浏览器必须要用一张真的图片

用状态码来判断是否请求成功


用script标签发送请求

button.onclick = function () {
      let script = document.createElement('script')
      script.src='/pay'
      document.body.appendChild(script)
      script.onload=function(){
        alert('success')
        amount.innerText = amount.innerText-1;
      }
      script.onerror=function(){
        alert('fail')
      }
    }
else if(path === '/pay'){
     var amount = fs.readFileSync('./db','utf8')//同步读一个文件
     var newAmount = amount - 1
     if(Math.random()>0.5){
       fs.writeFileSync('./db', newAmount)
       response.setHeader('Content-Type','application/javascript')
       response.statusCode = 200
       response.write(`alert('hehe') 
       amount.innerText = amount.innerText-1
       `)
     }
     else{
       response.statusCode = 400
       response.write('fail')
     }
     response.end()
  }

这样就可以不用使用 一张图片了,更加节省性能了
但是人们发现一件事,就是说如果成功了的话返回的script标签每次都会执行,所以就不用监听onload事件了,只需要监听onerror就可以了


image.png

优化

image.png

有人发现你不停的发送script请求,导致HTML里的script标签太多,怎么办,请求过后立即删除!

script.onload = function (e) {
        e.currentTarget.remove()
      }
      script.onerror = function (e) {
        alert('fail')
        e.currentTarget.remove()
      }

server rendered javascript 无刷新局部更新界面

get 请求不安全,如果没有防护措施,任何人都可以用一张图片,一个script标签去伪造请求,所以涉及到金钱等请求必须要用post

一个网站访问另一个网站的script

创建端口: PORT=8002 node server

修改hosts:
127.0.0.1 frank.com
127.0.0.1 jack.com
windows修改hosts
开启两个端口,一个8001,一个8002

用frank的前端访问Jack的后端


image.png

image.png

但是问题又来了


image.png

要解耦,服务端就执行你前端url里送过来的参数,函数在HTML中

 window.yyy = function (result) {
      if (result === 'success') {
        amount.innerText = amount.innerText - 1;
      } else {

      }
    }
    button.onclick = function () {
      let script = document.createElement('script')
      script.src = 'http://jack.com:8002/pay?callbackName=yyy'
      函数名包含在url中传输,callbackName  函数已经在前端写好了,这
      就解耦了,后端只要确认你执行哪个函数就行
      document.body.appendChild(script)
      script.onload = function (e) {
        e.currentTarget.remove()
      }
      script.onerror = function (e) {
        alert('fail')
        e.currentTarget.remove()
      }
    }
response.write(` 
       ${query.callbackName}.call(undefined,'{
         "success":true,
         "left":${newAmount}
       }')
       `)


什么是JSONP(自己理解)

后端响应前端最重要的就是这一块JSON,也有可能是对象,JSON和前后称为padding的部分合起来就是JSONP
JSON+padding = JSONP
大部分时间不一定是JSON,可能是String
那么就是'StringP'

image.png

什么是真正的JSONP

请求方:frank.com的前端程序员(浏览器)
响应方:Jack.com的后端程序员(服务器)
1.请求创建script,src指向响应方,同时传一个查询参数?callbackName=yyy
2.响应方根据查询参数callbackName,构造形如
1.yyy.call(undefined,'你要的数据')
2.yyy('你要的数据')
这样的响应
3.浏览器接到这样的响应,就会执行yyy.call(undefined,'你要的数据')
4.那么请求方就会知道了自己想要的数据
这就是JSONP

有两条规定:
1.回调callbackName统一规定为callback
2.函数名称为了不冲突覆盖 yyy改为随机数,例如frank123568454()


真正的JSONP写法

前台代码
  button.onclick = function () {
      let script = document.createElement('script')
      let functionName = 'frank' + parseInt(Math.random() * 1000000, 10)
      window[functionName] = function (result) {
        if (result === 'success') {
          amount.innerText = amount.innerText - 1;
        } else {

        }
      }
      script.src = 'http://jack.com:8002/pay?callback=' + functionName
      document.body.appendChild(script)
      script.onload = function (e) {
        e.currentTarget.remove()
        delete window[functionName]
      }
      script.onerror = function (e) {
        alert('fail')
        e.currentTarget.remove()
        delete window[functionName]
      }
    }
  后台代码
   var amount = fs.readFileSync('./db', 'utf8') //同步读一个文件
    var newAmount = amount - 1
    fs.writeFileSync('./db', newAmount)
    response.setHeader('Content-Type', 'application/javascript')
    response.statusCode = 200
    response.write(` 
       ${query.callback}.call(undefined,'{
         "success":true,
         "left":${newAmount}
       }')
       `)
    //说明jack的后端要对frank的前端代码细节要很熟悉
    //解耦
    response.end()
image.png

jquery jsonp使用方式

  $.ajax({
              url: "http://jack.com:8002/pay",
              dataType: "jsonp",
              success: function (response) {
                if (response === 'success') {
                  amount.innerText = amount.innerText - 1;
                }
              }
              })

jquery帮忙省了很多工作,比如callback自动生成,函数名自动生成,但是一个很坑的地方在于JSONP跟AJAX一点关系都没有,它却把jsonp使用归结到了ajax方法了

千万记住这两者不同


面试题:请问jsonp为什么不支持post???

因为jsonp是通过动态创建script实现的,动态创建script的时候只能使用get不能使用post!!

同源策略:域名相同,协议相同,端口相同
AJAX默认的是同源策略,有三种方法实现跨域1.JSONP2.WebSocket3.CROS

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 1. JSONP的实现原理 JSONP是通过动态创建script实现的。请求方:frank.com 的前端程序员(...
    王童孟阅读 466评论 0 2
  • 请先了解:《阮一峰:浏览器同源政策及其规避方法》 注意:请首先更新之前用过的 nodejs-test 代码,否则会...
    格林姆大师阅读 431评论 0 0
  • 前端操作数据库 首先,我们试着通过前端来操作一个数据库。数据库是什么?只要能长久的存数据,就是数据库。文件系统是一...
    是刘快啊阅读 370评论 0 2
  • JSONP 问:什么是JSONP? 1. 问题引入 在日常开发中,前端程序员想要从后端请求一些数据,是如何操作的呢...
    黄同学2019阅读 417评论 0 2
  • Jsonp 和 Ajax 有个毛关系啊!!! 这一点非常重要啊 大概是jQuery把Jsonp放到了ajax AP...
    squall1744阅读 612评论 2 3