chrome.runtime.sendMessage传大JSON报错:消息长度超限,求manifest.json调整方案
解决Chrome扩展
chrome.runtime.sendMessage传输大JSON对象的长度限制问题 问题描述
在通过chrome.runtime.sendMessage从content.js向background.js传输大体积JSON对象时,出现报错:
Uncaught Error: Message length exceeded maximum allowed length
相关代码如下:
Content.js
var ServerPath = "http://localhost:62513/api/account"; chrome.runtime.sendMessage({ method: 'POST', action: 'xhttp', url: ServerPath + "/rapdata", data: JSON.stringify({ data: data, fileName: fileName }) }, function (responseText) { //alert(responseText); console.log("response of call saverapdata method"); /*Callback function to deal with the response*/ });
Background.js
chrome.runtime.onMessage.addListener(function (request, sender, callback) { console.log("background js onMessage call."); var resp = "done"; if (request.action == "xhttp") { debugger; //alert(request.data);url: ServerPath + "/rapdata", var ServerPath = "http://localhost:62513/api/account"; $.ajax({ type: "POST", url: request.url, data: request.data, contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { debugger; console.log(data); //alert("Data: " + data); }, failure: function (response) { debugger; console.log(response); ///alert(response.d); } }); return true; // prevents the callback from being called too early on return } });
解决方案
先给你明确结论:没办法通过manifest.json来修改sendMessage的最大长度限制,这个限制是Chrome内核层面硬编码的,没法通过扩展配置调整。不过有几个靠谱的替代方案:
1. 用Chrome本地存储中转数据
这是最常用的方案,把大数据临时存在chrome.storage.local里,只通过sendMessage传输一个唯一标识key,background.js拿到key后再从存储里取数据:
修改后的Content.js:
var ServerPath = "http://localhost:62513/api/account"; // 生成唯一临时key,避免冲突 const tempDataKey = `large_payload_${Date.now()}_${Math.random().toString(36).substring(2)}`; // 把大对象存入本地存储 chrome.storage.local.set({ [tempDataKey]: { data: data, fileName: fileName } }, () => { // 只发送key和其他参数给background chrome.runtime.sendMessage({ method: 'POST', action: 'xhttp', url: ServerPath + "/rapdata", dataKey: tempDataKey }, (responseText) => { console.log("response of call saverapdata method"); // 回调后清理临时数据 chrome.storage.local.remove(tempDataKey); }); });
修改后的Background.js:
chrome.runtime.onMessage.addListener(function (request, sender, callback) { console.log("background js onMessage call."); if (request.action == "xhttp") { // 通过key从存储读取大数据 chrome.storage.local.get(request.dataKey, (result) => { const largePayload = result[request.dataKey]; if (!largePayload) { console.error("临时存储的数据不存在"); return; } const postData = JSON.stringify(largePayload); $.ajax({ type: "POST", url: request.url, data: postData, contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { console.log(data); // 处理完成后清理临时数据 chrome.storage.local.remove(request.dataKey); }, failure: function (response) { console.log(response); // 失败也清理数据 chrome.storage.local.remove(request.dataKey); } }); }); return true; // 保持消息通道开放 } });
2. 用长连接chrome.runtime.connect传输
chrome.runtime.connect建立的长连接比一次性的sendMessage支持更大的数据传输量,适合持续或大体积数据场景:
修改后的Content.js:
var ServerPath = "http://localhost:62513/api/account"; // 建立专用长连接 const port = chrome.runtime.connect({ name: "large_data_transfer" }); // 发送完整的大数据和请求参数 port.postMessage({ method: 'POST', action: 'xhttp', url: ServerPath + "/rapdata", data: { data: data, fileName: fileName } }); // 监听background的响应 port.onMessage.addListener((response) => { console.log("response of call saverapdata method:", response); port.disconnect(); // 任务完成关闭连接 });
修改后的Background.js:
chrome.runtime.onConnect.addListener((port) => { // 只处理指定名称的连接 if (port.name === "large_data_transfer") { port.onMessage.addListener((request) => { console.log("background js received data via long connection."); if (request.action == "xhttp") { const postData = JSON.stringify(request.data); $.ajax({ type: "POST", url: request.url, data: postData, contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { console.log(data); port.postMessage({ status: "success", result: data }); }, failure: function (response) { console.log(response); port.postMessage({ status: "failure", error: response }); } }); } }); } });
3. 压缩数据体积(可选)
如果数据实在太大,可以先对JSON字符串进行压缩(比如用pako库把数据压缩成base64格式),传输后再解压,能大幅减少传输体积。不过需要在扩展中引入第三方压缩库,适合极端大体积场景。
内容的提问来源于stack exchange,提问作者Mehul Prajapati
相关产品推荐
相关产品推荐

