本文主要介绍了Node做中转服务器转发接口的相关资料,需要的朋友可以参考下,希望能帮助到大家。
由于项目在做前后端分离,牵扯跨域和夸协议问题,临时抱佛脚,选择用nodejs做中转,我想应该好多人都用它。但是做普通的表单转发没啥问题,当处理附件上传转发时,各种蛋疼,已解决!
1.项目比较特殊,后台拥有两个平台,一个java一个donet,比较鸡肋,具体什么原因就不解释了。
2.当做node转发时,刚开始没有转发文件的操作,就做的很简单,用户传过来啥就,拦截到,进行转发,一切都很ok!
3.文件转发,就很麻烦。我的思路,将用户上传的文件存到node服务器。使用formidable 。
通过npm安装:
npm install formidable@latest
使用它进行文件转存,保存到临时目录得到文件信息。
再通过文件包重组。进行上传。注意此处上传必须遵循w3c上传文件表单标准,具体自己查资料。
其实思路很简单,但是实际操作起来还是挺麻烦,我中间也趟了好多坑,也是自己node不成熟,毕竟只是用来做中转!
直接上代码吧:看代码还是清晰:
server.js,用于启动服务并转发。
var http = require("http"); var url = require("url"); var fs = require('fs'); const querystring = require("querystring"); var path = require('path'); var formidable = require('formidable'), os = require('os'), util = require('util'); var config = require('./config').types; // var netServerUrlFlag = require('./config').netServerUrlFlag; var netServerhost = require('./config').netServerhost; var netServerport = require('./config').netServerport; var javaServerUrlFlag = require('./config').javaServerUrlFlag; var javaServerhost = require('./config').javaServerhost; var javaServerport = require('./config').javaServerport; var fileServerUrlFlag = require('./config').fileServerUrlFlag; var webapp = require('./config').webapp; var PORT = require('./config').webport; /** * 上传文件 * @param files 经过formidable处理过的文件 * @param req httpRequest对象 * @param postData 额外提交的数据 */ function uploadFile(files, req, postData) { var boundaryKey = Math.random().toString(16); var endData = '\r\n----' + boundaryKey + '--'; var filesLength = 0, content; // 初始数据,把post过来的数据都携带上去 content = (function (obj) { var rslt = []; Object.keys(obj).forEach(function (key) { arr = ['\r\n----' + boundaryKey + '\r\n']; arr.push('Content-Disposition: form-data; name="' + obj[key][0] + '"\r\n\r\n'); arr.push(obj[key][1]); rslt.push(arr.join('')); }); return rslt.join(''); })(postData); // 组装数据 Object.keys(files).forEach(function (key) { if (!files.hasOwnProperty(key)) { delete files.key; return; } content += '\r\n----' + boundaryKey + '\r\n' + 'Content-Type: application/octet-stream\r\n' + 'Content-Disposition: form-data; name="' + files[key][0] + '"; ' + 'filename="' + files[key][1].name + '"; \r\n' + 'Content-Transfer-Encoding: binary\r\n\r\n'; files[key].contentBinary = new Buffer(content, 'utf-8');; filesLength += files[key].contentBinary.length + fs.statSync(files[key][1].path).size; }); req.setHeader('Content-Type', 'multipart/form-data; boundary=--' + boundaryKey); req.setHeader('Content-Length', filesLength + Buffer.byteLength(endData)); // 执行上传 var allFiles = Object.keys(files); var fileNum = allFiles.length; var uploadedCount = 0; allFiles.forEach(function (key) { req.write(files[key].contentBinary); console.log("files[key].path:" + files[key][1].path); var fileStream = fs.createReadStream(files[key][1].path, { bufferSize: 4 * 1024 }); fileStream.on('end', function () { // 上传成功一个文件之后,把临时文件删了 fs.unlink(files[key][1].path); uploadedCount++; if (uploadedCount == fileNum) { // 如果已经是最后一个文件,那就正常结束 req.end(endData); } }); fileStream.pipe(req, { end: false }); }); } var server = http.createServer(function (request, response) { var clientUrl = request.url; var url_parts = url.parse(clientUrl); //解析路径 var pathname = url_parts.pathname; var sreq = request; var sres = response; // .net 转发请求 if (pathname.match(netServerUrlFlag) != null) { var clientUrl2 = clientUrl.replace("/" + netServerUrlFlag, ''); console.log(".net转发请求......" + clientUrl2); var pramsJson = ''; sreq.on("data", function (data) { pramsJson += data; }).on("end", function () { var contenttype = request.headers['content-type']; if (contenttype == undefined || contenttype == null || contenttype == '') { var opt = { host: netServerhost, //跨域访问的主机ip port: netServerport, path: clientUrl2, method: request.method, headers: { 'Content-Length': Buffer.byteLength(pramsJson) } } } else { var opt = { host: netServerhost, //跨域访问的主机ip port: netServerport, path: clientUrl2, method: request.method, headers: { 'Content-Type': request.headers['content-type'], 'Content-Length': Buffer.byteLength(pramsJson) } } } console.log('method', opt.method); var body = ''; var req = http.request(opt, function (res) { res.on('data', function (data) { body += data; }).on('end', function () { response.write(body); response.end(); }); }).on('error', function (e) { response.end('内部错误,请联系管理员!MSG:' + e); console.log("error: " + e.message); }) req.write(pramsJson); req.end(); }) } else // java 转发请求 if (pathname.match(javaServerUrlFlag) != null) { response.setHeader("Content-type", "text/plain;charset=UTF-8"); var clientUrl2 = clientUrl.replace("/" + javaServerUrlFlag, ''); console.log(".java转发请求......http://" + javaServerhost + ":" + javaServerport + "" + clientUrl2); var prams = ''; sreq.on("data", function (data) { prams += data; }).on("end", function () { console.log("client pramsJson>>>>>" + prams); const postData = prams; console.log("client pramsJson>>>>>" + postData); var contenttype = request.headers['content-type']; if (contenttype == undefined || contenttype == null || contenttype == '') { var opt = { host: javaServerhost, //跨域访问的主机ip port: javaServerport, path: "/hrrp" + clientUrl2, method: request.method, headers: { 'Content-Length': Buffer.byteLength(postData) } } } else { var opt = { host: javaServerhost, //跨域访问的主机ip port: javaServerport, path: "/hrrp" + clientUrl2, method: request.method, headers: { 'Content-Type': request.headers['content-type'], 'Content-Length': Buffer.byteLength(postData) } } } var body = ''; console.log('method', opt.method); var req = http.request(opt, function (res) { //console.log("response: " + res.statusCode); res.on('data', function (data) { body += data; }).on('end', function () { response.write(body); response.end(); //console.log("end:>>>>>>>" + body); }); }).on('error', function (e) { response.end('内部错误,请联系管理员!MSG:' + e); console.log("error: " + e.message); }) req.write(postData); req.end(); }) } else if (pathname.match(fileServerUrlFlag) != null) { //文件拦截保存到本地 var form = new formidable.IncomingForm(), files = [], fields = []; form.uploadDir = os.tmpdir(); form.on('field', function (field, value) { console.log(field, value); fields.push([field, value]); }).on('file', function (field, file) { console.log(field, file); files.push([field, file]); }).on('end', function () { // var clientUrl2 = clientUrl.replace("/" + fileServerUrlFlag, ''); var opt = { host: netServerhost, //跨域访问的主机ip port: netServerport, path: clientUrl2, method: request.method } var body = ''; var req = http.request(opt, function (res) { res.on('data', function (data) { body += data; }).on('end', function () { response.write(body); response.end(); }); }).on('error', function (e) { response.end('内部错误,请联系管理员!MSG:' + e); console.log("error: " + e.message); }) //文件上传 uploadFile(files, req, fields); }); form.parse(sreq); } else { var realPath = path.join(webapp, pathname); //这里设置自己的文件名称; var ext = path.extname(realPath); ext = ext ? ext.slice(1) : 'unknown'; fs.exists(realPath, function (exists) { //console.log("file is exists:"+exists+" file path: " + realPath + ""); if (!exists) { response.writeHead(404, { 'Content-Type': 'text/plain' }); response.write("This request URL " + pathname + " was not found on this server."); response.end(); } else { fs.readFile(realPath, "binary", function (err, file) { if (err) { response.writeHead(500, { 'Content-Type': 'text/plain' }); //response.end(err); response.end("内部错误,请联系管理员"); } else { var contentType = config[ext] || "text/plain"; response.writeHead(200, { 'Content-Type': contentType }); response.write(file, "binary"); response.end(); } }); } }); } }); server.listen(PORT); console.log("Server runing at port: " + PORT + ".");
config.js,用于配置。
exports.types = { "css": "text/css", "gif": "image/gif", "html": "text/html", "htm": "text/html", "ico": "image/x-icon", "jpeg": "image/jpeg", "jpg": "image/jpeg", "js": "text/javascript", "json": "application/json", "pdf": "application/pdf", "png": "image/png", "svg": "image/svg+xml", "swf": "application/x-shockwave-flash", "tiff": "image/tiff", "txt": "text/plain", "wav": "audio/x-wav", "wma": "audio/x-ms-wma", "wmv": "video/x-ms-wmv", "xml": "text/xml" }; exports.netServerUrlFlag = "NETSERVER"; exports.netServerhost = ""; exports.netServerport = ""; exports.javaServerUrlFlag = "JAVASERVER"; exports.javaServerhost = ""; //转发的地址 exports.javaServerport = "";//转发的端口 exports.fileServerUrlFlag="FileUpload"; exports.webapp = "public";//项目目录 exports.webport = "82"; //项目启动端口
相关推荐:
Atas ialah kandungan terperinci Node做中转服务器转发接口实例分享. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.

Memahami bagaimana enjin JavaScript berfungsi secara dalaman adalah penting kepada pemaju kerana ia membantu menulis kod yang lebih cekap dan memahami kesesakan prestasi dan strategi pengoptimuman. 1) aliran kerja enjin termasuk tiga peringkat: parsing, penyusun dan pelaksanaan; 2) Semasa proses pelaksanaan, enjin akan melakukan pengoptimuman dinamik, seperti cache dalam talian dan kelas tersembunyi; 3) Amalan terbaik termasuk mengelakkan pembolehubah global, mengoptimumkan gelung, menggunakan const dan membiarkan, dan mengelakkan penggunaan penutupan yang berlebihan.

Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Peralihan dari C/C ke JavaScript memerlukan menyesuaikan diri dengan menaip dinamik, pengumpulan sampah dan pengaturcaraan asynchronous. 1) C/C adalah bahasa yang ditaip secara statik yang memerlukan pengurusan memori manual, manakala JavaScript ditaip secara dinamik dan pengumpulan sampah diproses secara automatik. 2) C/C perlu dikumpulkan ke dalam kod mesin, manakala JavaScript adalah bahasa yang ditafsirkan. 3) JavaScript memperkenalkan konsep seperti penutupan, rantaian prototaip dan janji, yang meningkatkan keupayaan pengaturcaraan fleksibiliti dan asynchronous.

Enjin JavaScript yang berbeza mempunyai kesan yang berbeza apabila menguraikan dan melaksanakan kod JavaScript, kerana prinsip pelaksanaan dan strategi pengoptimuman setiap enjin berbeza. 1. Analisis leksikal: Menukar kod sumber ke dalam unit leksikal. 2. Analisis Tatabahasa: Menjana pokok sintaks abstrak. 3. Pengoptimuman dan Penyusunan: Menjana kod mesin melalui pengkompil JIT. 4. Jalankan: Jalankan kod mesin. Enjin V8 mengoptimumkan melalui kompilasi segera dan kelas tersembunyi, Spidermonkey menggunakan sistem kesimpulan jenis, menghasilkan prestasi prestasi yang berbeza pada kod yang sama.

Aplikasi JavaScript di dunia nyata termasuk pengaturcaraan sisi pelayan, pembangunan aplikasi mudah alih dan Internet of Things Control: 1. Pengaturcaraan sisi pelayan direalisasikan melalui node.js, sesuai untuk pemprosesan permintaan serentak yang tinggi. 2. Pembangunan aplikasi mudah alih dijalankan melalui reaktnatif dan menyokong penggunaan silang platform. 3. Digunakan untuk kawalan peranti IoT melalui Perpustakaan Johnny-Five, sesuai untuk interaksi perkakasan.

Saya membina aplikasi SaaS multi-penyewa berfungsi (aplikasi edTech) dengan alat teknologi harian anda dan anda boleh melakukan perkara yang sama. Pertama, apakah aplikasi SaaS multi-penyewa? Aplikasi SaaS Multi-penyewa membolehkan anda melayani beberapa pelanggan dari Sing


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Dreamweaver CS6
Alat pembangunan web visual

Muat turun versi mac editor Atom
Editor sumber terbuka yang paling popular

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

DVWA
Damn Vulnerable Web App (DVWA) ialah aplikasi web PHP/MySQL yang sangat terdedah. Matlamat utamanya adalah untuk menjadi bantuan bagi profesional keselamatan untuk menguji kemahiran dan alatan mereka dalam persekitaran undang-undang, untuk membantu pembangun web lebih memahami proses mengamankan aplikasi web, dan untuk membantu guru/pelajar mengajar/belajar dalam persekitaran bilik darjah Aplikasi web keselamatan. Matlamat DVWA adalah untuk mempraktikkan beberapa kelemahan web yang paling biasa melalui antara muka yang mudah dan mudah, dengan pelbagai tahap kesukaran. Sila ambil perhatian bahawa perisian ini