flask和axios如何发送和接收文件
how to send and receive file by flask and axios
在节点js中,我发送了一个post请求,希望从pythonflask服务器接收到一个文件。它发送的内容无关紧要,我只想从烧瓶服务器接收一个 jpeg 文件:
const fs = require('fs');
const axios = require('axios');
const BASE_URL = "http://localhost:5000";
function send_test(test_name,...args) {
const apiurl = `${BASE_URL}/send`;
const form = new URLSearchParams();
form.append('filename', test_name);
const config = {
headers: {
'content-type': 'multipart/form-data'
}
};
axios.request({
url: apiurl,
method: 'POST',
headers:config,
data: form,
})
.then(function (response) {
console.log(response.data);
fs.writeFileSync('result.jpeg',
response.data);
})
.catch(function (error) {
console.log(error);
});
}
result = send_test('test_name');
flask 服务器returns 一个jpeg,它从节点js 接收什么并不重要,它不检查表单,只发送一个jpeg 文件:
from flask import Flask, request,send_file
import os
app = Flask(__name__)
@app.route('/send', methods=['POST'])
def send():
print('send')
extracted_name = 'test.jpeg'
return send_file(extracted_name, mimetype="image/jpeg")
但是,当我将文件保存到'result.jpeg'时,文件无法打开。我认为文件的编码在这里很重要。如何通过fs.writeFileSync()保存文件? response.data 的前几个字节是这样的:
����JFIFHH��xExifII*1>i�FPicasa�0220��
����C
我无法从你的问题中看出你为什么要使用 post 请求。在我看来,一个get请求足以下载一个文件。
在下面的示例中,使用获取请求下载并保存了一个文件。 variable rule 用于 select 文件名。获取文件并保存为流。
function downloadFile(src, dst) {
axios
.get(src, { responseType: 'stream' })
.then(async resp => {
resp.data.pipe(fs.createWriteStream(dst));
});
}
downloadFile(
'http://localhost:5000/download/test.jpeg',
'result.jpeg'
);
@app.route('/download/<path:filename>')
def download(filename):
return send_from_directory(app.static_folder, filename)
如果您还想向服务器发送表单数据,您可以稍微修改示例以达到您的目的。
function downloadFile(src, dst) {
const url = 'http://localhost:5000/send';
const formData = new FormData();
formData.append('filename', src);
axios
.post(url, formData, { headers: formData.getHeaders(), responseType: 'stream' })
.then(async resp => {
resp.data.pipe(fs.createWriteStream(dst));
});
}
downloadFile(
'test.jpeg',
'result.jpeg'
);
如果你想用axios上传文件,我推荐下面的过程。
const url = 'http://localhost:5000/upload';
const filePath = path.resolve('result.jpeg');
fs.readFile(filePath, async (error, data) => {
if (error) {
console.log(error);
return;
}
const formData = new FormData();
formData.append('file', data, { filepath: filePath, contentType: 'image/jpg' });
axios
.post(url, formData, { headers: formData.getHeaders() })
.then(resp => {
console.log('File uploaded successfully.');
});
});
@app.route('/upload', methods=['POST'])
def upload():
file = request.files.get('file');
# Process the file here.
return '', 200
有多种方法可以将文件和 JSON 数据合二为一。
在 HTTP 中发送 JSON 数据 header:
from flask import send_file
import json
@app.route('/send')
def send_json_binary():
filename = 'test.jpeg'
resp = send_file(filename, mimetype='image/jpeg')
resp.headers['X-Metadata'] = json.dumps({
'filemeta': 'Your metadata here.'
})
return resp
function downloadFile(src, dst) {
axios
.get(src, { responseType: 'stream' })
.then(async resp => {
const meta = JSON.parse(resp.headers['x-metadata'])
const filemeta = meta.filemeta;
resp.data.pipe(fs.createWriteStream(dst));
});
}
downloadFile(
'http://localhost:5000/send',
'result.jpeg'
);
发送 Base64 编码数据 JSON:
from flask import jsonify
from base64 import b64encode
@app.route('/sample')
def send_json_binary():
filename = 'test.jpeg'
with open(filename, 'rb') as fh:
return jsonify(
filemeta = 'Your metadata here.',
filedata = b64encode(fh.read()).decode()
)
function downloadFile(src, dst) {
axios
.get(src, { responseType: 'json' })
.then(async resp => {
const meta = resp.data.filemeta;
const buffer = Buffer.from(resp.data.filedata, 'base64');
const stream = Readable.from(buffer);
stream.pipe(fs.createWriteStream(dst))
});
}
downloadFile(
'http://localhost:5000/send',
'result.jpeg'
);
走哪条路取决于你的要求。
在节点js中,我发送了一个post请求,希望从pythonflask服务器接收到一个文件。它发送的内容无关紧要,我只想从烧瓶服务器接收一个 jpeg 文件:
const fs = require('fs');
const axios = require('axios');
const BASE_URL = "http://localhost:5000";
function send_test(test_name,...args) {
const apiurl = `${BASE_URL}/send`;
const form = new URLSearchParams();
form.append('filename', test_name);
const config = {
headers: {
'content-type': 'multipart/form-data'
}
};
axios.request({
url: apiurl,
method: 'POST',
headers:config,
data: form,
})
.then(function (response) {
console.log(response.data);
fs.writeFileSync('result.jpeg',
response.data);
})
.catch(function (error) {
console.log(error);
});
}
result = send_test('test_name');
flask 服务器returns 一个jpeg,它从节点js 接收什么并不重要,它不检查表单,只发送一个jpeg 文件:
from flask import Flask, request,send_file
import os
app = Flask(__name__)
@app.route('/send', methods=['POST'])
def send():
print('send')
extracted_name = 'test.jpeg'
return send_file(extracted_name, mimetype="image/jpeg")
但是,当我将文件保存到'result.jpeg'时,文件无法打开。我认为文件的编码在这里很重要。如何通过fs.writeFileSync()保存文件? response.data 的前几个字节是这样的:
����JFIFHH��xExifII*1>i�FPicasa�0220�� ����C
我无法从你的问题中看出你为什么要使用 post 请求。在我看来,一个get请求足以下载一个文件。
在下面的示例中,使用获取请求下载并保存了一个文件。 variable rule 用于 select 文件名。获取文件并保存为流。
function downloadFile(src, dst) {
axios
.get(src, { responseType: 'stream' })
.then(async resp => {
resp.data.pipe(fs.createWriteStream(dst));
});
}
downloadFile(
'http://localhost:5000/download/test.jpeg',
'result.jpeg'
);
@app.route('/download/<path:filename>')
def download(filename):
return send_from_directory(app.static_folder, filename)
如果您还想向服务器发送表单数据,您可以稍微修改示例以达到您的目的。
function downloadFile(src, dst) {
const url = 'http://localhost:5000/send';
const formData = new FormData();
formData.append('filename', src);
axios
.post(url, formData, { headers: formData.getHeaders(), responseType: 'stream' })
.then(async resp => {
resp.data.pipe(fs.createWriteStream(dst));
});
}
downloadFile(
'test.jpeg',
'result.jpeg'
);
如果你想用axios上传文件,我推荐下面的过程。
const url = 'http://localhost:5000/upload';
const filePath = path.resolve('result.jpeg');
fs.readFile(filePath, async (error, data) => {
if (error) {
console.log(error);
return;
}
const formData = new FormData();
formData.append('file', data, { filepath: filePath, contentType: 'image/jpg' });
axios
.post(url, formData, { headers: formData.getHeaders() })
.then(resp => {
console.log('File uploaded successfully.');
});
});
@app.route('/upload', methods=['POST'])
def upload():
file = request.files.get('file');
# Process the file here.
return '', 200
有多种方法可以将文件和 JSON 数据合二为一。
在 HTTP 中发送 JSON 数据 header:
from flask import send_file
import json
@app.route('/send')
def send_json_binary():
filename = 'test.jpeg'
resp = send_file(filename, mimetype='image/jpeg')
resp.headers['X-Metadata'] = json.dumps({
'filemeta': 'Your metadata here.'
})
return resp
function downloadFile(src, dst) {
axios
.get(src, { responseType: 'stream' })
.then(async resp => {
const meta = JSON.parse(resp.headers['x-metadata'])
const filemeta = meta.filemeta;
resp.data.pipe(fs.createWriteStream(dst));
});
}
downloadFile(
'http://localhost:5000/send',
'result.jpeg'
);
发送 Base64 编码数据 JSON:
from flask import jsonify
from base64 import b64encode
@app.route('/sample')
def send_json_binary():
filename = 'test.jpeg'
with open(filename, 'rb') as fh:
return jsonify(
filemeta = 'Your metadata here.',
filedata = b64encode(fh.read()).decode()
)
function downloadFile(src, dst) {
axios
.get(src, { responseType: 'json' })
.then(async resp => {
const meta = resp.data.filemeta;
const buffer = Buffer.from(resp.data.filedata, 'base64');
const stream = Readable.from(buffer);
stream.pipe(fs.createWriteStream(dst))
});
}
downloadFile(
'http://localhost:5000/send',
'result.jpeg'
);
走哪条路取决于你的要求。