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

2022-03-31 11:34:56 +08:00
 yazoox

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

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

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

3545 次点击
所在节点    JavaScript
24 条回复
puzzle9
2022-03-31 11:39:41 +08:00
无头浏览器?
terranboy
2022-03-31 11:45:01 +08:00
定时任务?
nicevar
2022-03-31 11:53:49 +08:00
在客户端执行?看 js 多复杂了,简单的 js 解释器就行,如果复杂的话创建一个不可见的 webview 来处理,服务端可以用 headless chrome 。
shintendo
2022-03-31 11:58:04 +08:00
创建 script 标签不就行了
DrakeXiang
2022-03-31 11:59:03 +08:00
为啥不能在服务端干这个,客户端的话只能 eval 了吧,看起来挺不安全的样子
crysislinux
2022-03-31 12:01:33 +08:00
动态 import 就可以了,如果文件名会变化或者可能会加载多个文件,可以先 import 一个动态的列表,然后再根据列表 import 其他的。以前我用 systemjs 做过,现在可以用 dynamic import
ysc3839
2022-03-31 12:04:52 +08:00
先说清楚运行环境?是浏览器吗?
3dwelcome
2022-03-31 12:05:51 +08:00
@DrakeXiang 为什么都说客户端用 eval 不安全呢,我觉得挺安全啊。

又不是服务器远程调用 RPC 不安全,本地就算 JS 被注入修改,也不会影响到其他用户。
3dwelcome
2022-03-31 12:08:43 +08:00
而且浏览器环境下,chrome 插件拥有至高无上的权利,JS 代码随时随地会被入侵。

本来就没指望 JS 运行绝对的安全,用个 eval 或者创建 script 标签,都是常规操作了。
seakingii
2022-03-31 12:36:44 +08:00
浏览器的话,可以动态插入 script 到 dom 里.

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


....

后面自己搞定
Puteulanus
2022-03-31 13:15:49 +08:00
这不就是 JSONP 吗
icyalala
2022-03-31 13:24:48 +08:00
@3dwelcome 它要是拿了用户 token 传走,或者挂马攻击别人,再或者挂个挖矿的导致运营商封禁,这都有可能啊。
对面这种显然没有安全意识,如果你选择相信对面,结果对面被攻击了导致你程序影响用户,那最终你还得背锅。

另外浏览器插件里面乱搞这个屡见不鲜了: https://www.v2ex.com/t/390135 ,但使用插件的时候你的角色是用户,不是开发者了,你可以做出合理选择来保护自己。
DOLLOR
2022-03-31 13:53:15 +08:00
第三方应该只提供接口返回数据,而不是返回 js 代码。
dany813
2022-03-31 14:19:45 +08:00
6 楼说的不错,如果就一个 js 直接动态加载就行,你现在是没发确定有多少个 js ,需要一个 js 映射文件
libook
2022-03-31 14:37:38 +08:00
JS 动态在 DOM 树里插 script 标签就行。
或者浏览器比较新就动态 import 。

当然安全问题还是得考虑的,否则会有扯皮风险,可以考虑让客户的服务端提供处理数据的接口,或者前端加个沙盒机制从沙盒里跑客户的 js 文件。
ychost
2022-03-31 14:50:46 +08:00
为啥一定要 js ,他们给接口返回 JSON 不行吗,js 太 hack 了
yazoox
2022-03-31 17:12:38 +08:00
@seakingii 如果这段 js 运行完,有返回值,比如回返一个 json 文件,怎么获取到呢?
yazoox
2022-03-31 17:18:23 +08:00
@libook
"或者前端加个沙盒机制从沙盒里跑客户的 js 文件。"兄弟,这段话是什么意思?怎么在前端添加沙盒?
开一个 worker.js ?跑在这个里面,然后通过 postmessage 通讯?,etc.
seakingii
2022-03-31 17:27:23 +08:00
@yazoox 动态导入的 JS 你们约定好,里面有约定好的方法

比如你动态导入一个名字为 get_user_info_1.js ,里面必定有个同名的方法 get_user_info1_(你传入的数据)
seakingii
2022-03-31 17:28:45 +08:00
@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);

}
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/844060

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX