script / nodejs / gojs
s
https://gojs.net/latest/learn/
GoJS is a JavaScript library for implementing interactive diagrams. This page will show you the essentials of using GoJS. We assume you are a programmer who is familiar with HTML, CSS, and JavaScript.
https://gojs.net/latest/samples/
Node.js v14.2.0 文档
http://nodejs.cn/api/
简易上传功能index.js
const http = require('http'); const fs = require('fs'); const path = require('path'); var url = require("url"); const app = http.createServer(); const port = 3000; const ROOT_DIR = process.cwd(); const upload_page = ` <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>upload</title> </head> <body> <form action="/" method="post" enctype="multipart/form-data"> <input type="file" name="file" id="file" /> <br /> <input type="submit" name="submit" value="Submit" /> </form> </body> </html> ` function transfile(filepath, res) { const stream = fs.createReadStream(filepath); stream.pipe(res); } function save_file(filepath, filename, buf, callback) { const write_file = function () { filestream = fs.createWriteStream(path.join(filepath, filename)); filestream.write(buf); let msg = `${filename} saved.\n`; callback(null, msg); } // Check if the file exists in the current directory, and if it is writable. fs.access(filepath, fs.constants.F_OK | fs.constants.W_OK, (err) => { if (err) { if (err.code === 'ENOENT') { fs.mkdir(filepath, (err, fd) => { if (err) { callback(err) }else{ write_file(); } }) } else { console.error('is read-only'); callback(err); } } else { write_file(); } }); } function readDir(filepath, callback) { fs.readdir(filepath, (err, files) => { callback(err, files); }); } function show_upload_page(req, res) { res.end(upload_page); } function show_files(req, res) { var urlpath = url.parse(req.url).pathname; var filepath = path.join(ROOT_DIR, urlpath); fs.stat(filepath, (err, stats) => { if (err) { res.end(JSON.stringify(err)); } else if (stats.isFile()) { //download file content. var filestream = fs.createReadStream(filepath); res.writeHead(200, { 'Content-disposition': 'attachment; filename=' + path.basename(filepath) }); //here you can specify file name filestream.pipe(res); // also you can set content-type } else if (stats.isDirectory()) { //list files. readDir(filepath, (err, files) => { res.end(JSON.stringify(files)); }); } }); } const http_get = function (req, res) { var urlpath = url.parse(req.url).pathname; if (urlpath == '/upload') { show_upload_page(req, res); } else { show_files(req, res); } } const get_part = function (str, prefix, suffix) { let begin = str.indexOf(prefix); if (begin < 0) { return null; } begin = begin + prefix.length; let end = str.length; if (suffix) { end = str.indexOf(suffix, begin); } if (end < 0) { return null; } return str.substring(begin, end); } const http_post = function (req, res) { var urlpath = url.parse(req.url).pathname; var filepath = path.join(ROOT_DIR, urlpath); // const stream = fs.createReadStream(filepath); var content_type_header = req.headers['content-type'] if (!content_type_header) { res.end("wrong content-type"); } var boundary = get_part(content_type_header, 'boundary='); if (!boundary) { console.log("no boundary"); res.end(); return; } let chunks = []; // Readable streams emit 'data' events once a listener is added. req.on('data', (chunk) => { chunks.push(chunk); }); // The 'end' event indicates that the entire body has been received. req.on('end', () => { try { let head = '--' + boundary; let delimiter = '\r\n\r\n'; let buf = Buffer.concat(chunks); let delimiter_index = buf.indexOf(delimiter); let end_index = buf.indexOf('\r\n' + head); let begin_index = 0; while (delimiter_index > 0) {//found multi-part let filename = get_part(buf.toString('utf8', begin_index, delimiter_index), 'filename="', '"'); end_index = buf.indexOf('\r\n' + head, begin_index); if (filename && end_index > 0) { save_file(filepath, filename, buf.subarray(delimiter_index + delimiter.length, end_index), (err, msg) => { res.end(msg); } ) } if (end_index < 0) { break; } begin_index = end_index + head.length; delimiter_index = buf.indexOf(delimiter, end_index); } } catch (er) { // uh oh! bad json! console.log(er) res.statusCode = 400; return res.end(); } }); } app.on("request", (req, res) => { //get if (req.method == 'GET') { http_get(req, res); } else if (req.method == 'POST') { http_post(req, res); } else { res.end(); } }); app.listen(port, () => { console.log(`Server running at ${port}`); });
服务端,上传功能 linux 服务器启动
[root@sctssitapp234 ~]# node index.js
客户端:http://192.168.3.1/upload
客户端:http://192.168.3.1/index.js 可以下载该文件
end
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义