我想通过http访问文件,然后像"需要"本地文件一样提供功能。
local file_url = "http://127.0.0.1:800/myfile.lua"
local http = require("socket.http")
local remote = http.request(file_url)
require "remote"
我该怎么做
在require
中加载包的实际操作是由存储在package.searchers
表中的一系列函数执行的(在Lua 5.2+的说法中,5.1使用package.loaders
,但它是相同的思想(。您需要做的就是添加一个搜索器函数,该函数可以处理名称为URL的"包":
local http = require("socket.http")
local function http_loader(module_uri)
--I don't know what this function does, so I assume it returns the actual text of the file.
--If not, feel free to insert whatever the `socket` module needs to retrieve the text at the URI.
local module_text = http.request(module_uri)
--Always do error checking.
if --[[did the request succeed?]] 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"
。
相反,如果网络中有一些要预加载的特定模块,则可以使用packages.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) --Again, assuming this is the text.
--Always do error checking.
if --[[did the request succeed?]] 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" --Includes the loaded file.
现在,这两种方法都不会神奇地允许myfile.lua
中的任何模块访问网络资源。如果您使用第一种方法,并且myfile.lua
需要一些自身本地的资源(即:在服务器上(,那么它必须通过HTTP访问它们,就像在客户端上一样(因为这是加载它的地方(。
如果使用第二种方法,则必须按顺序http_preload
模块,以便没有模块尝试加载尚未预加载的资源。