這裡提供一個使用 Node-RED 透過 HTTP 請求送出與接收檔案的示範流程。以下是流程的概述:
送出檔案群組:
- 使用
inject
節點觸發流程。
function
節點用於格式化標頭和 payload。
http request
節點透過 POST 方法將檔案送至指定的 URL(http://localhost:1881/files
)。
debug
節點用於顯示送出請求的相關資訊。
接收檔案群組:
http in
節點設定接收檔案的 URL(/files)和使用 POST 方法。
debug
節點用於顯示接收請求的相關資訊。
change
節點用於設定回應的 payload 為 "okay"。
http response
節點用於回應 HTTP 請求。
file
節點用於將接收到的檔案寫入指定位置。
debug
節點用於顯示接收到的檔案內容。
在使用這個示範流程之前,你需要注意以下事項:
- 確保 Node-RED 已經安裝在你的系統上。
- 檔案送出的 URL 為
http://localhost:1881/files
,你需要確保這個端點正確設定。
⚠️ 我是在同一台 PC 上測試,因此開了兩個 Node-RED (分別使用 1880、1881 Port)。
⚠️ 實際上使用只能傳輸 txt 文字檔,其餘格式的檔案似乎會出錯。
示範流程
[
{
"id": "07799332fb2cb315",
"type": "tab",
"label": "檔案送出與接收",
"disabled": false,
"info": "",
"env": []
},
{
"id": "61f1812e8e841da3",
"type": "group",
"z": "07799332fb2cb315",
"name": "送出檔案",
"style": {
"label": true,
"fill": "#e3f3d3",
"fill-opacity": "0.2",
"stroke": "#addb7b",
"color": "#92d04f"
},
"nodes": [
"6a156025.b1c9f",
"9c0b2081.b1ac6",
"85c748e8.2d1f88",
"a4810d7a.f652a",
"fd62708f.a560a"
],
"x": 74,
"y": 39,
"w": 652,
"h": 142
},
{
"id": "2b6de2d20774e817",
"type": "group",
"z": "07799332fb2cb315",
"name": "接收檔案",
"style": {
"label": true,
"stroke": "#ff3f3f",
"fill": "#ffbfbf",
"fill-opacity": "0.32",
"color": "#ff3f3f"
},
"nodes": [
"c4f91df3.caef7",
"ef0aaf76.2236e",
"cc5a37cf.86c6d8",
"c14febc0.522db8",
"61d9c776d0fc2c5d",
"d98f7e19f5c85c49",
"8baa89ac7f9f9248"
],
"x": 74,
"y": 199,
"w": 572,
"h": 162
},
{
"id": "6a156025.b1c9f",
"type": "inject",
"z": "07799332fb2cb315",
"g": "61f1812e8e841da3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 80,
"wires": [
[
"fd62708f.a560a"
]
]
},
{
"id": "9c0b2081.b1ac6",
"type": "function",
"z": "07799332fb2cb315",
"g": "61f1812e8e841da3",
"name": "格式化標頭和 payload",
"func": "msg.headers = {\n \"Content-Type\": \"multipart/form-data; boundary=------------------------d74496d66958873e\"\n}\n\n\nmsg.payload = '--------------------------d74496d66958873e\\r\\n'+\n'Content-Disposition: form-data; name=\"select\"\\r\\n'+\n'\\r\\n'+\n'true\\r\\n'+\n'--------------------------d74496d66958873e\\r\\n'+\n'Content-Disposition: form-data; name=\"print\"\\r\\n'+\n'\\r\\n'+\n'true\\r\\n'+\n'--------------------------d74496d66958873e\\r\\n'+\n'Content-Disposition: form-data; name=\"file\"; filename=\"'+msg.filename+'\"\\r\\n'+\n'Content-Type: application/octet-stream\\r\\n'+\n'\\r\\n'+\nmsg.payload+'\\r\\n'+\n'--------------------------d74496d66958873e--\\r\\n';\n\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 220,
"y": 140,
"wires": [
[
"85c748e8.2d1f88"
]
]
},
{
"id": "85c748e8.2d1f88",
"type": "http request",
"z": "07799332fb2cb315",
"g": "61f1812e8e841da3",
"name": "",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "http://localhost:1881/files",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 460,
"y": 140,
"wires": [
[
"a4810d7a.f652a"
]
]
},
{
"id": "a4810d7a.f652a",
"type": "debug",
"z": "07799332fb2cb315",
"g": "61f1812e8e841da3",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 610,
"y": 140,
"wires": []
},
{
"id": "fd62708f.a560a",
"type": "file in",
"z": "07799332fb2cb315",
"g": "61f1812e8e841da3",
"name": "",
"filename": "path\\to\\file.txt",
"filenameType": "str",
"format": "",
"chunk": false,
"sendError": false,
"allProps": false,
"x": 310,
"y": 80,
"wires": [
[
"9c0b2081.b1ac6"
]
]
},
{
"id": "c4f91df3.caef7",
"type": "http in",
"z": "07799332fb2cb315",
"g": "2b6de2d20774e817",
"name": "",
"url": "/files",
"method": "post",
"upload": true,
"swaggerDoc": "",
"x": 160,
"y": 240,
"wires": [
[
"cc5a37cf.86c6d8",
"c14febc0.522db8",
"d98f7e19f5c85c49"
]
]
},
{
"id": "ef0aaf76.2236e",
"type": "http response",
"z": "07799332fb2cb315",
"g": "2b6de2d20774e817",
"name": "",
"statusCode": "",
"headers": {},
"x": 550,
"y": 240,
"wires": []
},
{
"id": "cc5a37cf.86c6d8",
"type": "debug",
"z": "07799332fb2cb315",
"g": "2b6de2d20774e817",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "req",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 360,
"y": 280,
"wires": []
},
{
"id": "c14febc0.522db8",
"type": "change",
"z": "07799332fb2cb315",
"g": "2b6de2d20774e817",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "okay",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 390,
"y": 240,
"wires": [
[
"ef0aaf76.2236e"
]
]
},
{
"id": "61d9c776d0fc2c5d",
"type": "file",
"z": "07799332fb2cb315",
"g": "2b6de2d20774e817",
"name": "",
"filename": "filename",
"filenameType": "msg",
"appendNewline": true,
"createDir": false,
"overwriteFile": "true",
"encoding": "none",
"x": 420,
"y": 320,
"wires": [
[
"8baa89ac7f9f9248"
]
]
},
{
"id": "d98f7e19f5c85c49",
"type": "function",
"z": "07799332fb2cb315",
"g": "2b6de2d20774e817",
"name": "接收檔案處理",
"func": "msg.payload = msg.req.files[0].buffer;\nmsg.filename = \"/data/\" + msg.req.files[0].originalname;\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 260,
"y": 320,
"wires": [
[
"61d9c776d0fc2c5d"
]
]
},
{
"id": "8baa89ac7f9f9248",
"type": "debug",
"z": "07799332fb2cb315",
"g": "2b6de2d20774e817",
"name": "debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 550,
"y": 320,
"wires": []
}
]
參考資源
https://flows.nodered.org/flow/cbf44e064b9406a1175a7e8d589f66ac