Chrome Extension V3实现可拖拽排序遇CSP及unsafe-eval问题求助
在Manifest V3 Chrome扩展中实现拖拽排序的CSP兼容方案
问题描述
我在开发基于Manifest V3的Chrome扩展时,想添加可拖拽排序功能,但不管用SortableJS库还是纯JS方案都踩了坑:
- 用SortableJS时触发CSP违规警告,违反
script-src 'self' 'wasm-unsafe-eval'指令 - 尝试纯JS方案也出现
unsafe-eval相关错误
当前扩展的CSP配置如下:
"content_security_policy": { "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self' 'wasm-unsafe-eval'; script-src-elem 'self' 'wasm-unsafe-eval';" }
我有两个在普通环境能运行的拖拽排序示例,但放到扩展里就用不了,现在想知道:
- 怎么在Chrome扩展里实现合规的拖拽排序功能?
- 拖拽排序功能必须依赖eval或其变体吗?
解决方案
1. 替换依赖eval的库/实现
拖拽排序完全不需要依赖eval或其变体,出现这类问题是因为你用的库或手写代码里隐式调用了eval、new Function()这类被CSP限制的API。
针对SortableJS的处理
SortableJS的部分版本会用new Function()做模板解析,你可以:
- 切换到SortableJS的无eval分支(比如只引入
sortable.core核心模块),避开带模板解析的功能 - 或者改用完全不依赖eval的轻量拖拽库,比如只引入
@shopify/draggable的基础拖拽模块
纯JS手写合规实现
自己写拖拽排序时,避开eval、new Function()这类API,用原生DOM事件就能实现:
// 纯JS合规拖拽排序示例 const list = document.getElementById('sortable-list'); let draggedItem = null; list.addEventListener('dragstart', (e) => { draggedItem = e.target; e.target.classList.add('dragging'); }); list.addEventListener('dragend', (e) => { e.target.classList.remove('dragging'); draggedItem = null; }); list.addEventListener('dragover', (e) => { e.preventDefault(); const afterElement = getDragAfterElement(list, e.clientY); afterElement ? list.insertBefore(draggedItem, afterElement) : list.appendChild(draggedItem); }); function getDragAfterElement(container, y) { const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]; return draggableElements.reduce((closest, child) => { const box = child.getBoundingClientRect(); const offset = y - box.top - box.height / 2; return offset < 0 && offset > closest.offset ? { offset, element: child } : closest; }, { offset: Number.NEGATIVE_INFINITY }).element; }
这段代码只用到原生drag系列事件,完全不涉及eval,符合Manifest V3的CSP要求。
2. 调整CSP(不推荐)
如果必须用依赖eval的库,虽然不推荐,但可以临时在CSP中添加'unsafe-eval',但这会降低扩展的安全性,不符合Manifest V3的安全规范:
"content_security_policy": { "extension_pages": "script-src 'self' 'wasm-unsafe-eval' 'unsafe-eval'; object-src 'self' 'wasm-unsafe-eval'; script-src-elem 'self' 'wasm-unsafe-eval' 'unsafe-eval';" }
强烈不建议这么做,因为unsafe-eval会引入XSS风险。
内容的提问来源于stack exchange,提问作者Verminous
相关产品推荐
相关产品推荐

