前端更优雅的使用 jsonp

前端更优雅的使用 jsonp

背景:最近项目中又使用到了 jsonp 这一项跨域的技术,(主要还是受同源策略影响),下面有为大家提供封装好的函数及对应使用示例,欢迎大家阅读理解

文章目录

  • 前端更优雅的使用 jsonp
    • 同源策略的介绍
    • JSONP 介绍
    • JSONP 的使用
      • 前端的 jsonp 异步函数封装
      • 服务端的逻辑示例

同源策略的介绍

同源策略是由 Netscape 公司提出的安全策略,现在所有支持 JavaScript 的浏览器都会使用这个策略。

所谓同源是指域名、协议、端口都相同。以 http://www.xxxxx.com:80/ 为例,http:// 为协议,域名是 www.xxxxx.com,端口是80。

为了安全,浏览器不允许进行跨域请求。当我们通过 Ajax 在网页和服务器之间发送或接收数据时,需要保证网页与所请求的地址是同源的,否则无法请求成功。同源策略可以防止 JavaScript 脚本从您的网站中读取数据,并将数据发送到其它的网站。如果没有同源策略,很有可能会有恶意的程序泄露您网站中的内容。

虽然同源策略在一定程度上提高了网站的安全,但也会给开发带来一些麻烦,例如在访问一些开发接口时,由于同源策略的存在,会调用失败。要解决这种问题就需要用到跨域,跨域的方法有许多种,其中最经典的就是 JSONP。

JSONP 介绍

JSONP 全称“JSON with Padding”,译为“带回调的 JSON”,它是 JSON 的一种使用模式。通过 JSONP 可以绕过浏览器的同源策略,进行跨域请求。

  • 在进行 Ajax 请求时,由于同源策略的影响,不能进行跨域请求,而 script 标签的 src 属性却可以加载跨域的 JavaScript 脚本,JSONP 就是利用这一特性实现的。

  • 与 Ajax 的区别:在使用 JSONP 进行跨域请求时,服务器不再返回 JSON 格式的数据,而是返回一段调用某个函数的 JavaScript 代码,在 src 属性中调用,来实现跨域。

  • 优点:JSONP 兼容性好,在一些老旧的浏览器种也可以运行。

  • 缺点:只能进行 GET 请求。

JSONP 的使用

前端的 jsonp 异步函数封装

思路:

  1. 每调用一次 jsonp,生成唯一的 callback 回调函数 key,注册在 window 对象。
  2. 后端收到请求后,返回一个以 callback 参数作为函数名的函数的调用和一系列参数。
  3. 响应完成,处理完数据后,自动的移除掉 script 标签,window 注册的回调函数。
// 序列化参数
function serializeParams(params: { [x: string]: string | number | boolean }) {
  return Object.keys(params)
    .map(
      (key) => encodeURIComponent(key) + "=" + encodeURIComponent(params[key])
    )
    .join("&");
}

function jsonp(url: string, params = {}) {
  // 生成唯一的回调函数名
  const callbackName: string = `jsonp_${Date.now()}`;

  const script = document.createElement("script");
  script.src = `${url}?${serializeParams(params)}&callback=${callbackName}`;
  document.body.appendChild(script);

  return new Promise((resolve, reject) => {
    // 注册全局回调函数
    window[callbackName] = (data: unknown) => {
      resolve(data);
      // 删除 script 标签
      document.body.removeChild(script);
      // 删除全局回调函数
      delete window[callbackName];
    };

    // 错误处理
    script.onerror = () => {
      reject(new Error("JSONP request failed."));
      // 删除 script 标签
      document.body.removeChild(script);
      // 删除全局回调函数
      delete window[callbackName];
    };
  });
}

前端 jsonp 使用示例:

  • 服务端对应处理下面 ↓
const getUserInfo = async () => {
  let apiRoot = "http://localhost:3000";
  let userInfo = await jsonp(`${apiRoot}/userInfo`, { name: "小名" });
  console.log(userInfo);
  //拿到数据处理逻辑即可
};
getUserInfo();

前端执行收到响应结果如下:
响应结果
打印结果

服务端的逻辑示例

思路:

  • 收到前端的请求后,根据参数信息返回调用前端函数名和一系列参数的 json 字符串的响应格式。
  • 该示例使用了 node express 框架,同学自行了解
let express = require("express"); //node 框架
let url = require("url");
let app = express();

app.get("/userInfo", function (req, res) {
  //参数解析
  let urlParams = url.parse(req.url, true);
  console.log(urlParams, "url参数");
  if (urlParams.query.callback) {
    let userInfoRes = `${urlParams.query.callback} (${JSON.stringify({
      name: urlParams.query.name ?? "张三",
      age: 21,
    })})`;
    console.log(userInfoRes, "jsonp 响应结果");
    res.end(userInfoRes);
  } else {
    res.end("404");
  }
});

app.listen(3000);

后端收到请求结果如下:
请求结果

总结:上述代码中

  • jsonp 的使用一定是前后端的紧密配合,文档的模糊也会导致后期维护艰难。

有疑问的同学可以私信我、对帮助到同学欢迎大家点赞、收藏评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/578977.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于车载点云数据的城市道路特征目标提取与三维重构

作者:邓宇彤,李峰,周思齐等 来源:《北京工业大学学报》 编辑:东岸因为一点人工一点智能公众号 基于车载点云数据的城市道路特征目标提取与三维重构本研究旨在弥补现有研究在处理复杂环境和大数据量上的不足&#xf…

Qt设置可执行程序图标,并打包发布

一、设置图标 图标png转ico: https://www.toolhelper.cn/Image/ImageToIco设置可执行程序图标 修改可执行程序图标 添加一个rc文件,操作如下,记得后缀改为rc 打开logo.rc文件添加代码IDI_ICON1 ICON DISCARDABLE "logo.ico"在项目pro后缀名的文件中添加代码 RC_…

系统盘空间不足调优方式1-APPData/大文件清理

作者:私语茶馆 1.前言 Windows系统盘(C盘)很容易剩余空间不足,这种情况下会非常影响Windows系统的运行,系统盘约束非常多,不方便在线扩容,因此规划和利用好系统盘是保障整体运行效率的关键。包…

机器人系统开发ros2-基础实践01-学会自定义一个机器人动作aciton实体类

您之前在了解操作教程中了解了action 。与其他通信类型及其各自的接口(主题/消息和服务/srv)一样,您也可以在包中自定义操作。本教程向您展示如何定义和构建可与您将在下一个教程中编写的action服务器和action 客户端一起使用的操作。 需要理…

Rust 实战练习 - 12. Axum Web 简单demo

Rust Web 历程 Rust 的异步框架tokio非他莫属,而web框架一直是悬而未决,说到底还是因为没有官方成熟的方案指引,大家各玩各的,互不兼容,白白浪费精力。 这个事情一直等到半官方组织tokio推出axum有了改善。但是市场上…

LeetCode455:分发饼干

题目描述 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个…

Orange3数据可视化(组件概览)

概要 大家见过Orange3提供的丰富数据可视化组件吗? Orange3为您提供了一系列生动的图表工具,包括树图、箱线图、小提琴图、分布图、散点图、折线图、条形图、筛图、马赛克图、自由投影、线性投影、雷达图、热力图、韦恩图、轮廓图、毕达哥拉斯树、毕达哥…

关于springboot内置tomcat最大请求数配置的一些问题

前言 springboot内置了tomcat。那么一个springboot web应用,最大的请求链接数是多少呢?很早以前就知道这个是有个配置,需要的时候,百度一下即可。但,事实并非如此,有几个问题我想大多数人还真不知道。比如…

强化学习-MAPPO算法解析与实践-Multi Agent Proximal Policy Optimization

一 算法简介 mappo 是一种将ppo算法扩展到多智能体情况的算法,在讨论过这种算法的论文中,比较有名和权威的是Nips2021上发表的《The Surprising Effectiveness of PPO in Cooperative》。比较遗憾的是,可能作者出于自己不是最早提出mappo算法…

Avalonia UI跨平台WPF

Avalonia是一个强大的框架,使开发人员能够使用.NET创建跨平台应用程序。 它使用自己的渲染引擎绘制UI控件,确保在Windows、macOS、Linux、Android、iOS和WebAssembly等不同平台上具有一致的外观和行为。 官网链接: 官网链接 文档链接&#…

mstsc 远程桌面由于以下原因之一无法连接到远程计算机

问题 想使用win自带的局域网远程工具mstsc远程连接电脑。如何连接:只需要两台电脑在同一个局域网内,然后使用被远程电脑的ip地址、Microsoft用户名和密码。 但是连接的时候会跳出来如下提示: 远程桌面由于以下原因之一无法连接到远程计算机…

【每日刷题】Day23

【每日刷题】Day23 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 138. 随机链表的复制 - 力扣(LeetCode) 2. 链表的回文结构_牛客题霸_牛客网 …

C++11新特性:lambda表达式

目录 1.lambda表达式 1.1 C98中的一个例子 1.2 lambda表达式 1.3 lamzbda表达式语法 1. lambda表达式各部分说明 2. 捕获列表说明 1.4 函数对象与lambda表达式 1.lambda表达式 1.1 C98中的一个例子 在C98中,如果想要对一个数据集合中的元素进行排序&#xff0…

spring的常用注解

目录 1.前言 2.web url映射 2.1RequestMapping 2.2PostMapping 2.3GetMapping 3.参数接受和接口响应 3.1RequestParam 3.2RequstBoby 3.3ResponseBoby 3.4RestController 4.bean的存储 4.1Controller 4.2Service 4.3Repository 4.4Compontent 4.5Configuration …

判断n以内的素数个数的五种方法+时间对比

目录 方法一:暴力法 复杂度 方法二:跨度为6的倍数的优化 复杂度 方法三:埃氏筛法 复杂度 方法四:埃氏筛法的改良 复杂度 方法五:线性筛 复杂度 性能对比测试 练习 方法一:暴力法 就是写一个函…

Nacos 集群 On K8s 实践服务注册发现、服务动态配置

一、K8s 部署 Nacos 集群 安装规划 组件replicas类型mysql1StatefulSetnacos3StatefulSet 使用 k8s 版本为:v1.18.0 。 本次使用 OpenEBS 来作为存储引擎,OpenEBS 是一个开源的、可扩展的存储平台,它提供了一种简单的方式来创建和管理持久…

JavaEE——Spring Boot入门

目录 📚 JavaEE——Spring Boot入门 🔧 1. 新建Spring Boot项目 🛠 2. 添加pom依赖 📝 3. 添加application.yml文件 📂 4. 创建Dao层 🔧 5. 创建Service层 🖥️ 6. 创建Controller层及HT…

easyExcel快速入门

目录 🧂1.简单介绍 🌭2.快速入门 🥓1.导入依赖 🍿2.导出到excel 🎏3.读入数据 🎉4.下载 1.简单介绍 传统操作Excel大多都是利用Apach POl进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多…

redisson分布式锁的单机版应用

package com.redis;/*** author linn* date 2024年04月23日 15:31*/ import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.…

多端文件互传软件-LocalSend

一、前言 日常学习或者是工作需求,需要手机和电脑互传文件。用到频率低的话,使用即时通讯软件也就够了。 像我日常使用的多端互传文件软件是LocalSend。 二、 LocalSend LocalSend是一款基于局域网的文件传输工具。 LocalSend是一种用于在本地网络中…