4

大家有没有在自己的代码里面,动态的下载并执行一段第三方的 js 文件或者代码?

 2 years ago
source link: https://www.v2ex.com/t/844060
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  JavaScript

大家有没有在自己的代码里面,动态的下载并执行一段第三方的 js 文件或者代码?

  yazoox · 15 小时 46 分钟前 · 1691 次点击

现在客户有一个需求,要在我们的一个包 /package ( React, typescript,编写的,用于显示数据的),展示数据的之前,要从客户的一个服务器上,下载一个.js 文件,执行一下,生成一些数据,导入到我们的数据中,然后再渲染展示数据。

这个 js 文件,是动态决定的。甚至可能不止一个。

这个有没有比较好的实践方法?

21 条回复    2022-03-31 18:39:39 +08:00

puzzle9

puzzle9      15 小时 41 分钟前

无头浏览器?

terranboy

terranboy      15 小时 36 分钟前

定时任务?

nicevar

nicevar      15 小时 27 分钟前

在客户端执行?看 js 多复杂了,简单的 js 解释器就行,如果复杂的话创建一个不可见的 webview 来处理,服务端可以用 headless chrome 。

shintendo

shintendo      15 小时 23 分钟前

创建 script 标签不就行了

DrakeXiang

DrakeXiang      15 小时 22 分钟前

为啥不能在服务端干这个,客户端的话只能 eval 了吧,看起来挺不安全的样子

crysislinux

crysislinux      15 小时 19 分钟前

动态 import 就可以了,如果文件名会变化或者可能会加载多个文件,可以先 import 一个动态的列表,然后再根据列表 import 其他的。以前我用 systemjs 做过,现在可以用 dynamic import

ysc3839

ysc3839      15 小时 16 分钟前

先说清楚运行环境?是浏览器吗?

3dwelcome

3dwelcome      15 小时 15 分钟前

@DrakeXiang 为什么都说客户端用 eval 不安全呢,我觉得挺安全啊。

又不是服务器远程调用 RPC 不安全,本地就算 JS 被注入修改,也不会影响到其他用户。

3dwelcome

3dwelcome      15 小时 12 分钟前

而且浏览器环境下,chrome 插件拥有至高无上的权利,JS 代码随时随地会被入侵。

本来就没指望 JS 运行绝对的安全,用个 eval 或者创建 script 标签,都是常规操作了。

seakingii

seakingii      14 小时 44 分钟前

浏览器的话,可以动态插入 script 到 dom 里.

var script = document.createElement('script'),
script.type = 'text/javascript';


....

后面自己搞定

Puteulanus

Puteulanus      14 小时 5 分钟前   ❤️ 1

这不就是 JSONP 吗

icyalala

icyalala      13 小时 56 分钟前   ❤️ 4

@3dwelcome 它要是拿了用户 token 传走,或者挂马攻击别人,再或者挂个挖矿的导致运营商封禁,这都有可能啊。
对面这种显然没有安全意识,如果你选择相信对面,结果对面被攻击了导致你程序影响用户,那最终你还得背锅。

另外浏览器插件里面乱搞这个屡见不鲜了: https://www.v2ex.com/t/390135 ,但使用插件的时候你的角色是用户,不是开发者了,你可以做出合理选择来保护自己。

DOLLOR

DOLLOR      13 小时 28 分钟前

第三方应该只提供接口返回数据,而不是返回 js 代码。

dany813

dany813      13 小时 1 分钟前

6 楼说的不错,如果就一个 js 直接动态加载就行,你现在是没发确定有多少个 js ,需要一个 js 映射文件

libook

libook      12 小时 43 分钟前

JS 动态在 DOM 树里插 script 标签就行。
或者浏览器比较新就动态 import 。

当然安全问题还是得考虑的,否则会有扯皮风险,可以考虑让客户的服务端提供处理数据的接口,或者前端加个沙盒机制从沙盒里跑客户的 js 文件。

ychost

ychost      12 小时 30 分钟前

为啥一定要 js ,他们给接口返回 JSON 不行吗,js 太 hack 了

yazoox

yazoox      10 小时 8 分钟前

@seakingii 如果这段 js 运行完,有返回值,比如回返一个 json 文件,怎么获取到呢?

yazoox

yazoox      10 小时 3 分钟前

@libook
"或者前端加个沙盒机制从沙盒里跑客户的 js 文件。"兄弟,这段话是什么意思?怎么在前端添加沙盒?
开一个 worker.js ?跑在这个里面,然后通过 postmessage 通讯?,etc.

seakingii

seakingii      9 小时 54 分钟前

@yazoox 动态导入的 JS 你们约定好,里面有约定好的方法

比如你动态导入一个名字为 get_user_info_1.js ,里面必定有个同名的方法 get_user_info1_(你传入的数据)

seakingii

seakingii      9 小时 52 分钟前

@yazoox

下面是例子代码,不一定能直接跑,没测试过

```
function importJsFile(jsUrl){

let jsId = hash(jsUrl);//根据 jsUrl 生成一个唯一的 hash 值,避免重复 import

if(document.getElementById(jsId)) return;


let newElement=document.createElement("script");
newElement.type="text/javascript";
newElement.id = jsId;
newElement.src=jsUrl;

var head=document.getElementsByTagName("head")[0];
head.appendChild(newElement);

}


function importJsAndInvoke(userId){
let functionName = 'get_user_info_1';
let jsUrl = 'http://baidu.com/js/get_user_info_1.js';

//导入外部 JS
importJsFile(jsUrl);

//调用外部 JS 里的一个方法
let result = window[functionName](userId);
console.dir(result);

}
```

libook

libook      8 小时 41 分钟前

@yazoox #16 我没有具体做过,我的思路就是用 WebWorkers 、WebAssembly 等天然提供沙盒的机制来跑,注意它们的沙盒基本是运行方面的隔离,一些同域的资源也可能可以访问,具体可以去 MDN 上仔细研究一下。
还可以找找看有没有一些前端沙盒的库,我听说 Deno 可以在浏览器端作为一个沙盒环境运行(本质好像也是 WebAssembly ),本人没用过,你可以去看一下是不是满足需要。

沙盒和外界程序之间使交流用 postmessage 等机制,对数据交流进行严格管制,就可以避免安全问题,同时记得记录关键日志(可以从前端发到你们自己的日志服务器),以便于审计和回溯。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK