🤔 还在为跨域问题头疼?JSONP 是你的答案!

前言

众所周知,JavaScript在前端与后端均可运行,但是运行环境有所不同。

  • 前端:现代浏览器(如 Chrome、Edge)中使用的是 V8 引擎来解析和执行 JavaScript 代码。
  • 后端:使用封装了V8引擎的Node.js运行开发者在后端运行JavaScript代码。但是相比于前端其剥离了html,而专注于网络应用后端。

而 JSONP(JSON with Padding)作为 json 的一种"使用模式",在前后端的实现当然有所不同。

什么是 jsonp?

jsonp 并非编程语言亦或者一项技术,而更像是开发者遗留下来的bug,使得程序员可以利用这个bug来实现跨域。

jsonp (JSON with Padding) 是 JSON 的一种"使用模式",用于解决主流浏览器的跨域数据访问的问题,简单来说就是让网站从一个域到另一个域获取资源。其优缺点也很明显,兼容一些很老的浏览器,但是只能进行GET请求。

那为什么我们到不同的网站(域)访问数据要通过 jsonp 这种"模式"呢?因为浏览器自带一种安全机制----同源策略。


同源策略

同源策略是由 Netscape 提出的一个著名的安全策略,目前所有支持 JavaScript 的浏览器都会使用这个策略,它主要用于限制一个源的文档或脚本如何与另一个源的资源进行交互,来防止跨域攻击和数据泄露。

如果两个页面的域名、协议、端口都相同,则可以认为两个页面为同源,即:源(Origin) = 域名(Domain) + 端口(Port) + 协议(Protocol)。

  • Protocol:用于访问资源的通信协议
    • 例如:http://https://为不同协议
  • Domain:域名是由一系列的子域名组成的,用于标识网站或服务器的位置
    • 例如:www.example.comapi.example.com,即使域名相同,但是子域名不同也视为不同源
  • Port:端口是用于区分不同应用程序或服务的数字标识符
    • 例如:http://example.com:8080http://example.com (8080 vs 默认80)

如果没有同源策略的限制,恶意网站可以通过 JavaScript 脚本读取用户在其他网站(比如银行网站)上登录后的敏感信息等,并将这些信息发送到攻击者的服务器。

当我们使用 AJAX 技术在网页和服务器之间发送或接收数据时,如果目标服务器和当前网页不是同源的,默认情况浏览器会阻止这种跨域请求。但是浏览器允许发起跨域请求,不过跨域请求返还的数据仍然会因为同源策略被浏览器拦截而无法被页面获取到。

jsonp 的使用

1.基于Node.js的服务端的JSONP格式

这里使用 node.js 早期的Commonjs模块化系统,在 ES6 模块化使用的是 import(例如:import http from 'http'

js 复制代码
// 通过 require 方法 引入Node.js的内置'http'模块
const http = require('http');

// 创建数据模拟数据库
const users = [
    {   id: 1, name: '张三'   },
    {   id: 2, name: '李四'   }
]

// 创建http服务器
const server = http.createServer((req, res) => {
    // 处理请求和响应
    res.end("callback(" + JSON.stringify(users) + ")")
})

// 启动服务器
server.listen(3000, () => {
    console.log('http服务在3000端口上启动了')
})

补充:

  • http请求处理在 node.js 中通常是异步的,并且 node.js 有非堵塞性,可以使其能够高效处理高并发场景。(即:在同一时间内处理大量来自不同用户端的请求)
  • 当一个 HTTP 请求发送到服务器时,与之绑定的回调函数将被执行。这个回调函数通常有两个参数:reqres
    • req(请求对象): 包含了所有关于请求的信息。
    • res(响应对象):使用 res 对象构造并发送响应给客户端。

用户端的请求到达服务端的执行流程为:

rust 复制代码
req(请求对象)接收请求后解析 -> 拿到资源 -> res(响应对象)返还响应 -> http连接结束

2.用户端发送请求

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="list">

    </ul>
    <script>
        let list = document.getElementById("list");
        // 定义 jsonp 函数
        let jsonp = (url, callback) => {
            let oScript = document.createElement('script');
            oScript.src = url;
            document.body.appendChild(oScript);
            window.callback = callback;
        }
        // 调用 jsonp 函数,向服务器发起 JSONP 请求,并处理返回的数据
        jsonp('http://localhost:3000/', (data) => {
            list.innerHTML = data.map(user => `
            <li>
                ${user.name}
            </li>
            `).join("");
        })
    </script>
</body>
</html>

解析:

  • JSONP 的核心是利用 <script> 标签可以跨域加载资源的特性。
  • 设置 <script> 标签的 src 属性为目标 URL,这样浏览器会自动向目标 URL 发送请求,然后将将 <script> 标签添加到页面的 <body> 中,触发请求。最后通过callback将服务器返还的数据传递给客户端。
相关推荐
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅11 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅11 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅12 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment12 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅12 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊12 小时前
jwt介绍
前端
爱敲代码的小鱼12 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte12 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc
NEXT0613 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法