路由設計
前後端不分離,模版渲染
建議:一個視圖函數寫一個url
獲取所有的項目:
/projects
def list_projects()
獲取單個項目內容:
/project/
def get_project()
修改某個項目內容:
/project_edit/
def edit_project()
前後端分離,通過method
/project
類的視圖
GET
獲取單個資源/project/
GET
獲取全部/projects
PUT
:修改資源POST
:創建資源DELETE
:刪除資源
一個簡單的ajax例子
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<p onclick="send_ajax()">點擊發送</p>
<script>
function send_ajax() {
$.ajax({
url: "http://127.0.0.1:5000",
data: JSON.stringify({username: "zhongxin"}),
dataType: 'json',
type: "POST",
contentType: 'application/json',
success: function (data) {
alert('成功')
}
})
}
</script>
</body>
</html>
python
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/',methods=['GET','POST'])
def index():
if request.method == 'GET':
return render_template('index.html')
elif request.method == 'POST':
print(request.json)
return '成功'
if __name__ == '__main__':
app.run()
使用ajax會返回X-Requested-With: XMLHttpRequest
可以在XHR
中找到
request
from flask import request
在request
中包含了全部的請求信息和環境信息
values
form
args
cookies
請求的cookies,dict類型
data
包含了請求數據,並轉換成字符串,無法處理的mimetype則會轉換成stream
stream
如果請求的表單無法解碼,則會無改動的保存到這裏。
當請求數據轉換string時,使用data是最好的方式,這個stream只返回數據一次
headers
請求頭,dict類型
files
通過POST或者PUT請求上傳的文件
environ
WSGI隱含的環境配置
method
請求方式
remote_addr
遠程IP
user-agent
提供反扒和惡意攻擊
文件上傳
增加文件類型限制,文件大小限制
import os
from flask import Flask, request, render_template, send_from_directory
app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 1024 * 1024 * 10 # 最大上傳文件大小
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
return render_template('index.html')
elif request.method == 'POST':
print(request.json)
return '成功'
def allowed_format(filename):
if os.path.splitext(filename)[-1].lower() not in ['jpg', 'png']:
return False
else:
return True
@app.route('/upload', methods=['GET', 'POST'])
def upload():
file = request.files.get('pic')
if file is None:
return render_template('index.html')
if allowed_format(file.filename):
file.save(file.filename)
return '保存成功'
return '保存失敗'
@app.route('/upload/<filename>')
def get_upload(filename):
return send_from_directory(os.getcwd(), filename)
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<p onclick="send_ajax()">點擊發送</p>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="pic">
<input type="submit">
</form>
<script>
function send_ajax() {
$.ajax({
url: "http://127.0.0.1:5000",
data: JSON.stringify({username: "zhongxin"}),
dataType: 'json',
type: "POST",
contentType: 'application/json',
success: function (data) {
alert('成功')
}
})
}
</script>
</body>
</html>
如果文件中存在空格,則可能出現問題
保存的時候需要添加secure_filename
from werkzeug.utils import secure_filename
file.save(secure_filename(file.filename))
響應頭
爲了返回一個json格式的內容,需要構造一個響應頭信息
方式一
import json
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
# 構造一個響應頭信息
return json.dumps({"username": "zhongxin"}), 201, {"content-type": "application/json"}
if __name__ == '__main__':
app.run()
方式二
import json
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def index():
r = make_response(json.dumps({"username": "zhongxin1"}), {"content-type": "application/json"})
return r
if __name__ == '__main__':
app.run()
查看make_response
的源碼:
def make_response(*args):
if not args:
return current_app.response_class()
if len(args) == 1:
args = args[0]
return current_app.make_response(args)
當沒有入參的時候進入current_app.response_class()
進入之後可以看到response_class = Response
class Response(ResponseBase, JSONMixin):
default_mimetype = "text/html"
def _get_data_for_json(self, cache):
return self.get_data()
@property
def max_cookie_size(self):
if current_app:
return current_app.config["MAX_COOKIE_SIZE"]
return super(Response, self).max_cookie_size
所以默認的響應頭就是"text/html"
方式三
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def index():
r = jsonify({"username": "zhongxin2"})
return r
if __name__ == '__main__':
app.run()
可以看一下jsonify
源碼,其實也就是用的make_response
中的 current_app.response_class
def jsonify(*args, **kwargs):
indent = None
separators = (",", ":")
if current_app.config["JSONIFY_PRETTYPRINT_REGULAR"] or current_app.debug:
indent = 2
separators = (", ", ": ")
if args and kwargs:
raise TypeError("jsonify() behavior undefined when passed both args and kwargs")
elif len(args) == 1: # single args are passed directly to dumps()
data = args[0]
else:
data = args or kwargs
return current_app.response_class(
dumps(data, indent=indent, separators=separators) + "\n",
mimetype=current_app.config["JSONIFY_MIMETYPE"],
)