在自己的电脑上实现一个JSONP

2017-12-31  本文已影响0人  没头脑很不高兴

数据库是什么

相当于是一个文件系统。可以长久地存储数据,就叫做数据库
在这里,用一个文件代表数据库,取名为db(没有后缀),在文件内输入 100 ,保存退出。我们现在要实现一个跨域打钱的功能

JSONP是什么

JSON是一种互联网通用的数据传输格式,P即padding,是包住JSON两边的一部分字符。JSONP可理解为跨域的请求。因为一般来说,在本域名下,是不能访问到其他域名下的资源的,JSONP是民间程序员发明的、用来请求其他域名下资源的工具。

在自己的电脑上如何跨域请求自己的资源?

  1. 安装一个http-server
    因为一般在本地打开一个页面调试的时候,一般都是适应的file资源,但是,有的类型的资源必须是通过http网络协议 才能访问的,可以在电脑上安装一个http-server
    安装方法
    npm install http-server -g
    安装完之后,进入目标文件夹,在命令行输入
    http-server -c-1
    就可以开启一个本地的服务器
    image.png

这两个IP地址看起来很眼熟,第一个是经常用来配置路由器的IP,第二个是电脑自己访问自己的时候的IP,因为前一个IP是路由器产生的,所以,在同一局域网的 手机也可以连接这个这个IP进行调试。

http-server这一部分可以不看,因为只是稍微提一下,我们完全可以自己用node配置一个本地的服务器,实现更多的功能

  1. 接下来修改一下Hosts文件:
    这样可以让自己的电脑在访问一个域名的时候提供一个电脑伪装的ip
  1. 用node写一个server
第一步,写一个index.html文件,把 js 代码也写在这里面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>jsonp</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h5>您的账户余额是</h5><span id="amount">&&&amount&&&</span>
    <button id="btn">-1s</button>
    <script>
        btn.addEventListener('click', (e)=>{
            let script = document.createElement('script')
            let functionName = 'frank'+ parseInt(Math.random()*10000000 ,10)  // 生成一个随机的函数名
            window[functionName] = function(result){ 
                if (result==='success'){
                    amount.innerText = amount.innerText - 0 - 1  // 避免刷新页面,前端和后台做同样的操作
                }else{
                    console.log('zhelicuol')
                }
                
            }
            // 这里在frank.com:8001下,请求 jack.com:8002的资源
            script.src = 'http://jack.com:8002/pay?callbackName=' + functionName
            document.body.appendChild(script)
            script.onload = function(e){
                console.log('onload')
                e.currentTarget.remove()
                delete window[functionName]  // 无论是否请求成功,都删掉发送过请求的script标签和函数名
            }
            script.error = function(e){
                e.currentTarget.remove()
                delete window[functionName] 
            }
        })
    
    </script>
</body>
</html>

我们把发送JSONP的代码也写在这里,就是通过点击按钮之后,就发送一个请求

第二步,写一个style.css的文件
button{
    background: red;
}

虽然这里给定了button的样式,但是后端并没有前端返回这个文件

第三部,自己用node.js配置后台的文件

因为我们是前端,不需要对这个有过多的了解,只需要明白中间的路由配置方法就可以了,其他部分在需要的时候都可以复制直接用
代码如下

var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]

if (!port) {
  console.log('请指定端口号好不啦?\nnode server.js 8888 这样不会吗?')
  process.exit(1)
}

var server = http.createServer(function (request, response) {
  var parsedUrl = url.parse(request.url, true)
  var pathWithQuery = request.url
  var queryString = ''
  if (pathWithQuery.indexOf('?') >= 0) { queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
  var path = parsedUrl.pathname
  var query = parsedUrl.query
  var method = request.method

  /******** 从这里开始看,上面不要看 ************/

  if (path === '/') {
    var string = fs.readFileSync('./index.html', 'utf-8')
    var amount = fs.readFileSync('./db', 'utf-8')
    string = string.replace('&&&amount&&&', amount)
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(string)
    response.end()
  } else if(path == '/style.css'){
    response.setHeader('Content-Type','text/css;charset=utf-8')
    response.write('body{color:green;}')  // 后台自己写的css
    response.end()
  }else if (path === '/pay') {
    var amount = fs.readFileSync('./db', 'utf-8')
    var newAmount = amount - 1
    fs.writeFile('./db',newAmount,function err(error) {
      console.log(error)
    })
    response.setHeader('Content-Type','text/javacript;charset=utf-8')
    response.write(`
      ${query.callbackName}.call(undefined,'success')
    `)
    response.end()
  } else {
    response.statusCode = 404
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write('404了')
    response.end()
  }

  /******** 代码结束,下面不要看 ************/
})

server.listen(port)
console.log('监听 ' + port + ' 成功\n请用在空中转体720度然后用电饭煲打开 http://localhost:' + port)

中间需要看的部分是路由的设置,可以看到,如果用户请求了 /style.css这个路径,后台并没有返回style.css这个文件,而是自己做了一个假的信息响应给浏览器。


image.png

这个时候,文件夹里面有这些文件(README.md是github加的文件,不用管)

使用JSONP
  1. 使用命令行,进入这个目录
  2. 输入 node index.js 8001
  3. 另外再打开一个gitbash(或者其他命令行工具),在这个目录下输入 node index.js 8002
  4. 使用浏览器访问 frank.com:8001 ,点击按钮,就可以让fran.com的域名给jack.com的域名发送。并且接收请求了
JSONP的原理

JSONP不是官方提供的跨域的方法,而是古代的前端程序员为了实现跨域利用script标签自创的一个方法

它的本质上和 页面引入一个 CDN 的jQuery是一样的

如果在页面中写
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js></script>"
浏览器就会下载 https://cdn.bootcss.com/jquery/3.3.1/jquery.js 这个url里面的JS代码,并且将其展示到 html 文件中
这段代码可以是立即执行的,并且它可以完成一些功能

上一篇下一篇

猜你喜欢

热点阅读