先说成功的示例:
js部分:
function add(x, y) {
return x + y
}
.py文件调用js
import execjs
# 运行环境
print(execjs.get().name)
# 返回值:Node.js(V8)
# 简单示例:
with open('add.js') as file:
js_function = file.read()
ctx = execjs.compile(js_function)
x = 2
y = 8
print(ctx.call('add', x, y))
# 成功返回:10
出错的代码:
function _linik(params) {
let dCode = atob(params);
return decodeURI(dCode)
}
let params = 'aHR0cHM6Ly9kb3dubG9h'
console.log(_linik(params))
如果是直接运行上面这个js文件是成功执行的
但是如果用py文件调用就出错
调用出错的完整代码为:
js部分:
function _linik(params) {
let dCode = atob(params);
return decodeURI(dCode)
}
py部分:
import execjs
params = 'aHR0cHM6Ly9kb3dubG9h'
with open('get_link.js') as file:
jscode = file.read()
ctx = execjs.compile(jscode)
ctx.call('_linik', params)
经过打印发现 就是这个call报错了
以下是报错内容:
Node.js (V8)
10
function _linik(params) {
let dCode = atob(params);
return decodeURI(dCode)
}
let params = 'aHR0cHM6Ly9kb3dubG9hZC1wcm8uY2pqZDIwLmNvbS8xMjMtNTU3LzY1M2UzMWQxLzE2NzU3MzItMC82NTNlMzFkMThiNjAwNjI3YjVkN2IxNTMzM2U3ODIyZD92PTImdD0xNjc0MjA2NjI5JnM9ZjkxMzU2NjVlMGM4ZWE5NGVhMTEzNTVjMzg3ZWI1ZjYmZmlsZW5hbWU9V2luJUU3JTg5JTg4K1BTKzIwMjIucmFy'
console.log(_linik(params))
_external_runtime.ExternalRuntime.Context object at 0x000002D8552B92D0>
Exception in thread Thread-3 (_readerthread):
Traceback (most recent call last):
File "D:\Program Files\Python\Python311\Lib\threading.py", line 1038, in _bootstrap_inner
self.run()
File "D:\Program Files\Python\Python311\Lib\threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "D:\Program Files\Python\Python311\Lib\subprocess.py", line 1552, in _readerthread
buffer.append(fh.read())
^^^^^^^^^
UnicodeDecodeError: 'gbk' codec can't decode byte 0x88 in position 158: illegal multibyte sequence
Traceback (most recent call last):
File "D:\farml\PycharmProjects\django_farmllar\Apps\BaiduYunPan\tests.py", line 40, in
ctx.call('linik', params)
File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_abstract_runtime_context.py", line 37, in call
return self._call(name, *args)
^^^^^^^^^^^^^^^^^^^^^^^
File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 92, in _call
return self._eval("{identifier}.apply(this, {args})".format(identifier=identifier, args=args))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 78, in _eval
return self.exec_(code)
^^^^^^^^^^^^^^^^
File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_abstract_runtime_context.py", line 18, in exec_
return self._exec_(source)
^^^^^^^^^^^^^^^^^^^
File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 88, in _exec_
return self._extract_result(output)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\farml\PycharmProjects\venv\Lib\site-packages\execjs\_external_runtime.py", line 156, in _extract_result
output = output.replace("\r\n", "\n").replace("\r", "\n")
^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'replace'
这个错误是由于 atob 和 decodeURI 两个函数是 JavaScript 的内置函数,在 Node.js 中可以正常使用,但是在 execjs 模块中不能使用。
解决方法有两种:
使用 JavaScript 的第三方库,如 "js-base64",在 js 文件中导入,然后替换 atob 和 decodeURI 两个函数。
在 Python 中手动实现 atob 和 decodeURI 函数,然后在 js 代码中使用这两个 Python 函数。
还有一点是提醒你阅读错误信息,在报错信息中可以看到是UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 2: illegal multibyte sequence,这是因为你的文件编码是gbk,而你的python环境编码是utf-8,所以会产生编码错误。可以在读取文件时加上编码格式'utf-8'。
根据你的错误提示,是编码的问题。进入subprocess.py文件修改,将encoding=None修改为encoding=‘utf-8’
参考:https://baijiahao.baidu.com/s?id=1745903738695011227&wfr=spider&for=pc&searchword=%E8%B0%83%E7%94%A8js%E6%96%87%E4%BB%B6%E6%8A%A5%E9%94%99gbk%20codec%20can%27t%20decode%20byte%200x88
望采纳!!!