У меня есть другое решение, свободное от ограничений по размеру. Также он не требует каких-либо других веб-серверов, вы можете отправить файл прямо с вашей рабочей станции. Файл ниже обеспечивает как загрузку, так и загрузку в/из чипа.
Редактировать: я разработал исходные примеры ниже в файловый менеджер, способный загружать, переименовывать, создавать резервные копии, удалять и, конечно же, обслуживать файлы, работающий на ESP8266. Проект можно найти здесь. (Зависит от NodeMCU.)
К сожалению, он не использует стандартную схему загрузки, используемую веб-браузерами, файл javascript, который загружается в него, предоставляется в конце. Можно создать ярлык для js в папке «Отправить», таким образом добавив его в список параметров «Отправить» в контекстном меню для каждого файла, но он будет способен обрабатывать выборки только одного файла. (Для обработки нескольких выбранных файлов потребуется расширение оболочки.)
Он поддерживает обычную загрузку через браузер.
Обратите внимание, что эта схема критически зависит от определенного соглашения XMLHTTPRequest, а именно, что тело POST отправляется во втором/последующем кадре после запроса. Если бы это было не так, код должен был бы найти первый \r\n\r\n в полезной нагрузке исходного запроса и добавить данные, которые следовали за этим, в файл.
headerBlock = "\r\nContent-type: text/html\r\nConnection: close\r\nAccess-Control-Allow-Origin: *\r\nCache-Control: no-cache\r\n\r\n"
local currentFileName = ""
local isPostData = false
print("filexfer")
local srv=net.createServer(net.TCP, 60)
srv:listen(80,
function(conn)
local function writefile(name, mode, data)
if (file.open("temp_" .. name, mode) == nil) then
return -1
end
file.write(data)
file.close()
end
conn:on("disconnection",
function(conn)
isPostData = false
end
)
conn:on("sent",
function(conn)
currentFileName = ""
isPostData = false
conn:close()
end
)
conn:on("receive",
function(conn, payload)
tmr.wdclr();
local s, e, m, buf, k, v
local tbl = {}
local i = 1
local retval = ""
if isPostData then
writefile(currentFileName, "a+", payload)
else
s, e = string.find(payload, "HTTP", 1, true)
if e ~= nil then
buf = string.sub(payload, 1, s - 2)
for m in string.gmatch(buf, "/?([%w+%p+][^/+]*)") do
tbl[i] = m
i = i + 1
end
m = nil
if #tbl > 2 then
local cmd = tbl[2]
if (tbl[3] ~= nil) and (tbl[3] ~= "/") then
currentFileName = tbl[3]
--else return an error
end
if (cmd == "put") then
writefile(currentFileName, "w+", "")
end
if (cmd == "append") then
isPostData = true
end
if (cmd == "persist") then
file.rename("temp_" .. currentFileName, currentFileName)
end
buf = ""
if retval == nil then
retval = "[nil]"
end
buf = "HTTP/1.1 200 OK" .. headerBlock .. retval
else
local filename = "index.html"
if tbl[2] ~= nil and tbl[2] ~= "/" then
filename = tbl[2]
end
require("fileupload")(conn, filename)
buf = ""
end
conn:send(buf)
end
end
end
)
end
)
Это fileupload.lua, на который ссылается вызов require в строке 75 (загрузить, потому что чип отправляет файл запрашивающему хосту). Он облегчает загрузку файлов любого размера с помощью обычного браузера. Если имя файла не передается, по умолчанию используется index.html.
local module =...
return function(conn, fname)
local buf
tmr.wdclr()
if file.list()[fname] ~= nil then
file.open(fname, "r")
buf = "HTTP/1.1 200 OK" .. headerBlock
else
file.open("error404.html", "r")
buf = "HTTP/1.1 404 FILE NOT FOUND" .. headerBlock
end
conn:on ("sent",
function(sck)
function sendfile(sck)
buf = file.read(255)
if buf ~= nil then
sck:send(buf)
else
sck:close()
if module ~= nil then
package.loaded[module] = nil
end
module = nil
return
end
end
sck:on("sent", sendfile)
sck:on("disconnection",
function(sck)
print("[disconnection fileupload.sendfile]", node.heap())
end
)
sendfile(sck)
end
)
conn:on ("receive",
function(sck, pl)
sck:close()
end
)
if buf == nil then
buf = ""
end
conn:send(buf)
end
А это клиентский javascript-файл, используемый для загрузки в чип. Передайте полный или относительный путь к загружаемому файлу в качестве первого/единственного аргумента. (Если аргументы не переданы, будет выдана ошибка.)
var filepath = WScript.Arguments(0);
var fso = new ActiveXObject("Scripting.FileSystemObject");
var str = fso.OpenTextFile(filepath, 1);
var file = fso.GetFile(filepath);
var filename = file.Name;
var buf = "";
var xhr = new ActiveXObject("MSXML2.XMLHTTP.6.0");
xhr.open("GET", "http://192.168.4.1/put/" + filename, false);
xhr.send();
while (str.AtEndOfStream == false)
{
buf = str.read(255);
xhr.open("POST", "http://192.168.4.1/append/" + filename, false);
xhr.send(buf);
}
str.close();
xhr.open("GET", "http://192.168.4.1/persist/" + filename, false);
xhr.send();
person
Mark McGinty
schedule
20.05.2016