-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrunjs.py
87 lines (73 loc) · 2.66 KB
/
runjs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import os
import json
import subprocess
'''
代替 execjs 执行 js,为了指定编码而写
'''
class RunJs:
def __init__(self, filepath: str = None, content: str = None, encoding: str = 'utf-8', back_status: bool = False):
"""
:param path: js 路径
:param content: js
:param encoding: 编码格式
:param back_status: 是否返回执行状态
"""
self._filepath = filepath
self._encoding = encoding
self._back_status = back_status
# 检查文件是否存在
if self._filepath is not None:
if not os.path.exists(self._filepath):
raise FileNotFoundError(f'文件不存在:{self._filepath}')
else:
with open(self._filepath, 'r', encoding=self._encoding) as f:
self._content = f.read()
else:
self._content = content
if self._filepath is None and self._content is None:
raise NotImplementedError('请输入 js 路径或者 js 内容!')
def run(self, *args, timeout: int = 5):
"""
:param args: 输入参数
:param timeout: 执行最大时间
:return:
"""
# 构造执行函数
if len(args) == 1:
return_str = '''
%s()
''' % args[0]
else:
return_str = '''
%s.apply(this, %s)
''' % (args[0], list(args)[1:])
# 构造新函数
new_content = '''
(function(){
const runJsProcess = process;
%s
console.log('nodeBack over!'); // 存在的意义就是下面换行用
runJsProcess.stdout.write(JSON.stringify({nodeBack:%s}));
})()
''' % (self._content, return_str)
# 执行新函数
p = subprocess.Popen(['node'], stdin=-1, stdout=-1, stderr=-1, universal_newlines=True, encoding=self._encoding)
stdout, stderr = p.communicate(input=new_content, timeout=timeout)
ret = p.wait()
# 判断返回
if ret != 0:
if self._back_status:
return {'status': False, 'result': stderr}
return stderr
if self._back_status:
return {'status': True, 'result': json.loads(stdout.split('\n')[-1])['nodeBack']}
return json.loads(stdout.split('\n')[-1])['nodeBack']
if __name__ == '__main__':
# run_js = RunJs(filepath='test.js')
run_js = RunJs(content='''
function getCookie(){
return arguments
}
''')
result = run_js.run('getCookie', 'Gk')
print(result)