Lua怎样从远程HTTP中require一个文件

我想要访问一个通过HTTP协议来获取的文件,并且可以像require一个本地文件一样使用文件中的函数.

local file_url = "http://127.0.0.1:800/myfile.lua"

local http = require("socket.http")
local remote = http.request(file_url)
require "remote"

我该怎样实现?

点赞
用户734069
用户734069

实际上,在require载入程序包的就是存储在“package.searchers”表中的一系列函数(在Lua 5.2+的说法中是这样的,5.1使用“package.loaders”,但是原理是相同的)。你需要做的是添加一个可以处理URL命名的“程序包”的搜索器函数:

local http = require("socket.http")

local function http_loader(module_uri)

    --我不知道这个函数的作用是什么,所以我假设它返回文件的实际文本。
    --如果不是,请随意插入`socket`模块需要检索URI文本的内容。
    local module_text = http.request(module_uri)

    --始终进行错误检查。
    if --[[请求是否成功?]] then
        return loadstring(module_text)
    else
        return "could not find HTTP module name " .. module_uri
    end
end

table.insert(package.searchers, http_loader)

有了它,你应该可以直接执行require "http://127.0.0.1:800/myfile.lua"

如果你有一些特定的网络模块要预加载,你可以使用package.preload表。例如,如果你想使用模块名称“remote”预加载位于http://127.0.0.1:800/myfile.lua的Lua文件,可以这样做:

local http = require("socket.http")

local function http_preload(module_uri, module_name)
    local module_text = http.request(module_uri) --再次假定这是文本。

    --始终进行错误检查。
    if --[[请求是否成功?]] then
        package.preload[module_name] = loadstring(module_text)
        return true
    else
        return nil, "could not find HTTP module name " .. module_uri
    end
end

assert(http_preload("http://127.0.0.1:800/myfile.lua", "remote"))

require "remote" --包括已加载的文件。

现在,这些方法都不会神奇地允许从myfile.lua中访问网络资源的所有模块。如果你使用第一种方法,而myfile.lua需要一些本地资源(即服务器上的资源),那么它必须像客户机一样通过HTTP访问它们(因为它是从客户机下载的)。

如果你使用第二种方法,你将不得不按顺序http_preload加载模块,以便没有模块尝试加载尚未预加载的资源。

2019-09-22 21:38:53