python-flask-上传文件时表单提交报错:Method Not Allowed
环境:
本地环境:win10 / centos6 , python3
flask入门:
python-flask结合bootstrap实现网页小工具实例-半小时速通版_bootstrap flask-CSDN博客
https://blog.csdn.net/pxy7896/article/details/137854455
python-flask-上传多个文件并存储_flask 上传多个文件-CSDN博客
https://blog.csdn.net/pxy7896/article/details/141026464
问题描述
很简单的一个工具:<form>
里上传一个文件,点击提交按钮,前端向后台传送这个文件,进行异步计算,然后返回结果,利用返回结果修改某些<div>
,让用户可以下载结果。完整流程在 python-flask结合bootstrap实现网页小工具实例-半小时速通版 已经写明,但现在遇到 405 错误:
The method is not allowed for the requested URL.
可能原因
当出现"Method Not Allowed"错误时,通常意味着在使用Flask时向特定URL发送了不被允许的HTTP请求方法。
- 检查路由是否定义了POST/GET
@app.route('/example', methods=['GET', 'POST'])
- 检查是否使用了正确的HTTP方法。例如,如果路由只允许GET请求,而前端发送了一个POST请求,就会导致"Method Not Allowed"错误
- 检查Flask应用的配置:有时候"Method Not Allowed"错误可能是由于应用配置或中间件问题引起的
解决
最后发现是我表单写错了。
<form action="example" ...>
...
<div class="row">
<button class="btn btn-primary" id="input-design-submit">提交</button>
</div>
</form>
这里提交按钮就不应该用button
,应该用input
。
因为这个按钮的点击事件要带着上传的文件发post请求,而这个异步请求,跟form的action,有个先后问题,或者说可能会冲突。
改为下面这样就ok了。
<input type="button" value="提交"/>
完整解法:
前端:
<form action="run_command_res" enctype="multipart/form-data" name="main_form" id="main_form" >
<!-- 略去一些内容 -->
<div class="row">
<input name="attach" type="file" id="customFile" lang="ch">
</div>
<div class="row">
<input type="button" value="提交" class="btn btn-primary" id="input-design-submit" />
</div>
</form>
<script>
$("#input-design-submit").click(function () {
// 构造数据
var formData = new FormData();
var attachFile = document.getElementById("customFile").files[0];
if (attachFile == null) {
var blob = new Blob([], {type: "text/plain;charset=utf-8"});
formData.append("attach", blob);
} else {
formData.append("attach", attachFile);
}
$(this).disabled = true; // 暂时禁用
$.ajax({
type: 'POST',
url: "/run_command_res",
data: formData,
processData: false, // jQuery不要处理发送的数据
contentType: false, // jQuery不要设置Content-Type请求头
success: function (resp){
var obj = jQuery.parseJSON(resp);
var code = obj.code;
if (code == 1) {
// 成功
} else {
// 失败
}
}
});
$(this).disabled = false; // 恢复
});
</script>
后端:
@app.route('/run_command_res', methods=['POST'])
def run_command_res():
'''
xxx design
'''
if request.method == 'POST':
files = request.files.getlist('attach')
res = {}
code = 1 # if fail, 0
# save file
f = files[0] # only first file
f.save('path/to/file')
// do something
# result
res["code"] = code
return json.dumps(res)
表单提交简化版
上面的情况是,前端向后端发送请求,后端处理后向前端返回数据,然后更新前端页面。如果不需要后端回传数据,可以只由form提交。此时的实现方案是:
前端:(不用写js了)
<form method="POST" enctype="multipart/form-data" action="run_command_res" name="main_form" id="main_form" >
<!-- 略去一些内容 -->
<div class="row">
<input name="attach" type="file" id="customFile" lang="ch">
</div>
<div class="row">
<button class="btn btn-primary">提交</button>
</div>
</form>
后端:(获取文件的方式变了)
@app.route('/run_command_res', methods=['POST'])
def run_command_res():
'''
xxx design
'''
if request.method == 'POST':
# save file
# 通过name获取文件
f = request.files['attach']
f.save('path/to/file')
# do something
return render_template('xxx.html')