由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;

可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称作JSONP(注意:根据JSONP的实现原理,知晓,JSONP只支持Get请求);

实现过程:

1.在客户端定义一个回调方法,预定义对数据的操作;

2.再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;

3.服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;

4.客户端拿到服务器返回得字符串之后,当作Script脚本去解析执行,这样就能够拿到JSONP的数据了;

  1. //客户端.html
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <script>
  11. function show() {
  12. console.log('ok')
  13. }
  14. </script>
  15. <script src="http://127.0.0.1:3000/getscript"></script>
  16. <!-- 上面的script就相当于下面
  17. <script>
  18. show()
  19. </script> -->
  20. </body>
  21. </html>
  1. //app.js
  2. const http = require('http')

  3. const server = http.createServer()

  4. server.on('request', function (req, res) {
  5. const url = req.url

  6. if (url === '/getscript') {
  7. //拼接一个合法的JS脚本,这里拼接的是一个方法的调用
  8. var scriptStr = 'show()'
  9. //res.end 发送给 客户端, 客户端去把 这个 字符串,当作JS代码去解析执行
  10. res.end(scriptStr)
  11. } else {
  12. res.end('404')
  13. }
  14. })
  15. server.listen(3000, function () {
  16. console.log('server')
  17. })

既然知道了原理就可以对其进行升级改造了。

上面我们的方法是写死的,但是后端并不知道我们的方法名是什么,我们用带参的形式传递给后端。

  1. //客户端.html
  2. ...
  3. <script>
  4. function show() {
  5. console.log('ok')
  6. }
  7. </script>
  8. <script src="http://127.0.0.1:3000/getscript?callback=show"></script>
  1. //app.js
  2. const http = require('http')
  3. const urlModule = require('url')

  4. const server = http.createServer()

  5. server.on('request', function (req, res) {

  6. const {pathname: url,query} = urlModule.parse(req.url, true)

  7. if (url === '/getscript') {
  8. //拼接一个合法的JS脚本,这里拼接的是一个方法的调用
  9. var scriptStr = `${query.callback}()`
  10. //res.end 发送给 客户端, 客户端去把 这个 字符串,当作JS代码去解析执行
  11. res.end(scriptStr)
  12. } else {
  13. res.end('404')
  14. }
  15. })
  16. server.listen(3000, function () {
  17. console.log('server')
  18. })

现在前端修改了方法名,只要改变请求参数,后端依旧能够使用。但是这只是单纯方法的调用,并没有发挥后端的作用呀。别着急,接下来就是获取数据

  1. //客户端.html
  2. ...
  3. <script>
  4. function showInfo123(data) {
  5. console.log(data)
  6. }
  7. </script>
  8. <script src="http://127.0.0.1:3000/getscript?callback=showInfo123"></script>
  1. //app.js
  2. ...
  3. server.on('request', function (req, res) {
  4. const {
  5. pathname: url,
  6. query
  7. } = urlModule.parse(req.url, true)

  8. if (url === '/getscript') {
  9. //拼接一个合法的JS脚本,这里拼接的是一个方法的调用
  10. var data = {
  11. name: 'caicaicai',
  12. age: 18,
  13. gender: 'man'
  14. }
  15. //data对象不能直接往字符串里拼,所以使用JSON.stringfy(),对data进行转换
  16. var scriptStr = `${query.callback}(${JSON.stringify(data)})`
  17. //res.end 发送给 客户端, 客户端去把 这个 字符串,当作JS代码去解析执行
  18. res.end(scriptStr)
  19. } else {
  20. res.end('404')
  21. }
  22. })
  23. ...

从浅入深——理解JSONP的实现原理的更多相关文章

  1. JavaScript基础知识从浅入深理解(一)

    JavaScript的简介 javascript是一门动态弱类型的解释型编程语言,增强页面动态效果,实现页面与用户之间的实时动态的交互. javascript是由三部分组成:ECMAScript.DO ...

  2. 浅入深出之Java集合框架(下)

    Java中的集合框架(下) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,哈哈这篇其实也还是基础,惊不惊喜意不意外 ̄▽ ̄ 写文真的好累,懒得写了.. ...

  3. 浅入深出Vue:工具准备之PostMan安装配置及Mock服务配置

    浅入深出Vue之工具准备(二):PostMan安装配置 由于家中有事,文章没顾得上.在此说声抱歉,这是工具准备的最后一章. 接下来就是开始环境搭建了~尽情期待 工欲善其事必先利其器,让我们先做好准备工 ...

  4. 浅入深出Vue:前言

    浅入深出Vue系列文章 之前大部分是在做后端,后来出于某些原因开始接触Vue.深感前端变化之大,各种工具.框架令人眼花缭乱.不过正是这些变化,让前端开发更灵活. 博主在刚开始时,参考官网的各个步骤以及 ...

  5. 『浅入深出』MySQL 中事务的实现

    在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的:在这篇文章中,我们将对事务的实现进行分析,尝 ...

  6. 浅入深出Vue:代码整洁之封装

    深入浅出vue系列文章已经更新过半了,在入门篇中我们实践了一个小小的项目. <代码整洁之道>一书中提到过一句话: 神在细节中 这句话来自20世纪中期注明现代建筑大师 路德维希·密斯·范·德 ...

  7. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  8. 浅入深出之Java集合框架(上)

    Java中的集合框架(上) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

  9. 浅入深出之Java集合框架(中)

    Java中的集合框架(中) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

随机推荐

  1. L2 Softmax与分类模型

    softmax和分类模型 内容包含: softmax回归的基本概念 如何获取Fashion-MNIST数据集和读取数据 softmax回归模型的从零开始实现,实现一个对Fashion-MNIST训练集 ...

  2. stand up meeting 1/13/2016

    part 组员                工作              工作耗时/h 明日计划 工作耗时/h    UI 冯晓云  UI测试和调整:与主程序完成合并    6 查漏补缺,扫除UI ...

  3. 终于明白if __name__ == '__main__':了

    其实很简单 if __name__ == '__main__': 就是一个判断 __name__是系统变量 __name__有一个特性,在当前文件运行是__main__,调用文件就是调用文件的路径了 ...

  4. 程序选择结构if和switch的定义以及使用方法

       什么是if选择结构 if选择结构是根据条件判断之后在做处理 基本的if选择结构的语法 if(条件){//条件为真则执行代码1,否则不执行  //代码块1 }   if-else选择结构 为什么使 ...

  5. pytorch LSTM情感分类全部代码

    先运行main.py进行文本序列化,再train.py模型训练 dataset.py from torch.utils.data import DataLoader,Dataset import to ...

  6. 2019-2020-1 20199326《Linux内核原理与分析》第二周作业

    本周总结:本周的学习内容主要是庖丁解牛Linux的第一章,然后看完书后,又跟着云班课加深学习了一下第一章的内容.第一章主要讲述了linux里的汇编指令的一些指令,比如movl,pushl,popl等等 ...

  7. pip安装openvc-python国内镜像源

    采用清华大学的镜像源. pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghu ...

  8. 12.Python提供了哪些内建类型

    There are mutable and Immutable types of Pythons built in types Mutable built-in types: List Set Dic ...

  9. telnet 636端口不通

    今天发生了一件奇怪的事情,LDAP的636端口突然就不通了报错如下 [www@DC ~]$ telnet 10.219.90.173 636Trying10.219.90.173...Connecte ...

  10. C#读写ini

    using System; using System.IO; using System.Runtime.InteropServices; using System.Text;   namespace ...