Note that unlike json.encode function, json.decode
doesn’t have any special features to support binary data.
It means that if you want to get a binary object encoded by
json.encode back, you need to decode data from base64 yourselves.
This can be done in a Lua script using base64 module.

A library to encode/decode strings to/from Base64. It provides 2 functions:
base64.encode and base64.decode. These functions are
handy if you need to pass some binary data in a JSON request or response.

Note that base64.decode may return a non-UTF-8 Lua string, so the result
may be unsafe to pass back to Splash (as a part of main function result
or as an argument to splash methods). It is fine if you know the original
data was ASCII or UTF8, but if you work with unknown data, “real” binary
data or just non-UTF-8 content then call treat.as_binary on the result
of base64.decode.

Returns:(s,content_type) pair: a Lua string with raw data and
its Content-Type.

treat.as_string “unwraps” a binary object and
returns a plain Lua string which can be processed from Lua.
If the resulting string is not encoded to UTF-8 then it is still possible to
process it in Lua, but it is not safe to return it as a main result
or pass to Splash functions. Use treat.as_binary to convert
processed string to a binary object if you need to pass it back to Splash.

There is no autodetection of table type because {} Lua table
is ambiguous: it can be either a JSON array or as a JSON object.
With table type autodetection it is easy to get a wrong output:
even if some data is always an array, it can be suddenly exported
as an object when an array is empty. To avoid surprises Splash requires
an explicit treat.as_array call.

To setup the path for Lua modules start Splash with --lua-package-path
option. --lua-package-path value should be a semicolon-separated list
of places where Lua looks for modules. Each entry should have a ? in it
that’s replaced with the module name.

If you use Splash installed using Docker see
Folders Sharing for more info on how to setup
paths.

Note

For the curious: --lua-package-path value is added to Lua
package.path.

When you use a Lua sandbox (default) Lua require
function is restricted when used in scripts: it only allows to load
modules from a whitelist. This whitelist is empty by default, i.e. by default
you can require nothing. To make your modules available for scripts start
Splash with --lua-sandbox-allowed-modules option. It should contain a
semicolon-separated list of Lua module names allowed in a sandbox:

Another way to write such module is to add a method to splash
object. This can be done by adding a method to its Splash
class - the approach is called “open classes” in Ruby or “monkey-patching”
in Python.

-- wait_for.lua-- Sandbox is not enforced in custom modules, so we can import-- internal Splash class and change it - add a method.localSplash=require("splash")functionSplash:wait_for(condition)whilenotcondition()doself:wait(0.05)endend-- no need to return anything

Which style to prefer is up to the developer. Functions are more explicit
and composable, monkey patching enables a more compact code. Either way,
require is explicit.

As seen in a previous example, sandbox restrictions for standard Lua modules
and functions are not applied in custom Lua modules, i.e. you can use
all the Lua powers. This makes it possible to import third-party Lua modules
and implement advanced features, but requires developer to be careful.
For example, let’s use os
module:

-- evil.lualocalos=require("os")localevil={}functionevil.sleep()-- Don't do this! It blocks the event loop and has a startup cost.-- splash:wait is there for a reason.os.execute("sleep 2")endfunctionevil.touch(filename)-- another bad ideaos.execute("touch "..filename)end-- todo: rm -rf /returnevil