FTP 使用 Microsoft Azure 功能通过 HTTP

FTP over HTTP using a Microsoft Azure function

我必须使用 Microsoft Azure 功能通过 HTTP 设置 FTP,但是当尝试连接到 FTP 服务器时,客户端超时并抛出 "ERR_GENERIC_CLIENT" 错误,并且退出。我确定问题来自 FTP 客户端配置,但我找不到要更改的内容。 天蓝色函数:

let Client = require('ssh2-sftp-client');
let client = new Client();
module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    const boundary = req.headers['content-type'].split('=')[1];
    const splitedBody = req.body.toString().split(boundary);
    let parsedBody = {};
    let errors = [];
    splitedBody.forEach(field => {
        if (field.includes('name=')) {
            if (!field.includes('filename')) {
                let regex = /name="(.*?)"\r\n\r\n(.*)/g;
                let m = regex.exec(field);
                parsedBody[m[1]] = m[2];
            }
            else {
                let regex = /Content-Type:\s(.*?)\s\s(((.*)\s)*)--/;
                let m = regex.exec(field);
                let file = field.split(m[1])[1]
                file = file.substring(4, file.length - 4);
                fileBuffer = Buffer.from(file);
                let fileNameRegex = /filename="(.*?)"/g;
                let fileName = fileNameRegex.exec(field)[1];
                parsedBody.file = file;
                parsedBody.buffer = fileBuffer;
                parsedBody.fileName = fileName;
            }
        }
    });
    const config = {
        host: parsedBody.host,
        port: parseInt(parsedBody.port),
        username: parsedBody.user,
        password: parsedBody.password,
        tryKeyboard: true,
        readyTimeout: 5000
    };
    try {
        await client.connect(config);
        try {
            let result = await client.put(
                parsedBody.buffer,
                parsedBody.path,
                {
                    flags: 'w',  // w - write and a - append
                    encoding: null, // use null for binary files
                    mode: 0o666, // mode to use for created file (rwx)
                    autoClose: true // automatically close the write stream when finished
                })
        }
        catch (e) {
            errors.push({e, msg: 'put'});
            context.log(`main error: ${e.message}`);
        }
    }
    catch (e) {
        errors.push({e, msg: 'connect'});
        context.log(e);
    }
    finally {
        client.end();
    }
    context.res = {
        body: {
            config,
            errors
        }
    };
};

为了测试,我使用了一个小的虚拟 HTML 形式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ftp over http</title>
</head>
<body>
                <form action="azure function URL" enctype="multipart/form-data" method="post">
                    <input type="hidden" name="host" value="ftp.server.address">
                    <input type="hidden" name="port" value="21">
                    <input type="hidden" name="path" value="/test/">
                    <input type="hidden" name="user" value="username">
                    <input type="hidden" name="password" value="password">
            <div>
                Text field title: <input type="text" name="title" /></div>
            <div>
                File: <input type="file" name="file" /></div>
            <input type="submit" value="Upload" />
        </form>
</body>
</html>```
When I submit the form all I receive is the unhelpfull and undocumented "ERR_GENERIC_CLIENT" code.

根据您提供的代码,您使用 sdk ssh2-sftp-client 连接 ftp 服务器。这是错误的。我们可以用它来连接 sftp 服务器。如果你想连接 ftp 服务器,我建议你使用 sdk basic-ftp。 sdk的使用方法请参考https://github.com/patrickjuchli/basic-ftp.

例如

  1. 代码
const ftp = require("basic-ftp")
const client = new ftp.Client()
module.exports = async function (context, req) {
module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    const boundary = req.headers['content-type'].split('=')[1];
    const splitedBody = req.body.toString().split(boundary);
    let parsedBody = {};
    let errors = [];
    splitedBody.forEach(field => {
        if (field.includes('name=')) {
            if (!field.includes('filename')) {
                let regex = /name="(.*?)"\r\n\r\n(.*)/g;
                let m = regex.exec(field);
                parsedBody[m[1]] = m[2];
            }
            else {
                let regex = /Content-Type:\s(.*?)\s\s(((.*)\s)*)--/;
                let m = regex.exec(field);
                let file = field.split(m[1])[1]
                file = file.substring(4, file.length - 4);
                fileBuffer = Buffer.from(file);
                let fileNameRegex = /filename="(.*?)"/g;
                let fileName = fileNameRegex.exec(field)[1];
                parsedBody.file = file;
                parsedBody.buffer = fileBuffer;
                parsedBody.fileName = fileName;
            }
        }
    });



client.ftp.verbose = true
    try {
        await   client.access({
            host: parsedBody.host,
        port: parseInt(parsedBody.port),
        user: parsedBody.user,
        password: parsedBody.password

        })
        var stream =getStream(parsedBody.buffer)
        const result =await client.upload(stream,parsedBody.path)
        context.log(result)

    }
    catch(err) {
        context.log(err)
        errors += err
    }
    client.close()

    context.res = {
        body: {
            errors
        }
    };











 };
  1. 测试(我用邮递员做测试)

  1. 连接到FTP服务器查看(我用的是FileZilla