fastapi是一个运行在python环境的非常强的api接口
先pip install “fastapi[all]"来拉取fastapi的库
我学的基本上是为了和前端互通的:
对了,想让虚拟机来运行fastapi要用
uvicorn python文件名:fastapi实例对象名 --reload --host 0.0.0.0 --port 8000
--reload是为了动态修改,--host是绑定的ip,这里设置为默认路由是为了让所有网络都能访问,--port是绑定的端口
服务端的main.py
我使用的虚拟机作为存放数据库的服务端,main.py文件也存在语虚拟机上,下面的html是在我的物理机上的
如下代码,这是main.py,运行在服务端,使用uvicorn main:app --reload --host 0.0.0.0来运行
from fastapi import FastAPI, Form
from fastapi.middleware.cors import CORSMiddleware
from pymysql import Connection
app = FastAPI()
//防止cors请求失败
app.add_middleware(
CORSMiddleware,
allow_origins="*",
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.post('/write_user/')
def run(username: str = Form(), password: str = Form(), password_again: str = Form()):
conn = Connection(
host="192.168.253.128",
port=3306,
user="root",
password="123"
)
conn.select_db("user_info")
cursor = conn.cursor()
cursor.execute("insert into base_info values (\'" + username + "\',\'" + password + "\')")
conn.commit()
conn.close()
return "OK"
@app.get('/user_info/')
def run():
conn = Connection(
host="192.168.253.128",
port=3306,
user="root",
password="123"
)
conn.select_db("user_info")
cursor = conn.cursor()
cursor.execute("select * from base_info")
result = cursor.fetchall()
return result
接受api的数据
下面是用javascript的XMLHttpReqeust来接收从想要网址传来发的数据
1.异步get到API的响应
let xhr = new XMLHttpRequest()
xhr.open('GET', 'http://192.168.253.128:8000/user_info', true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
let response = JSON.parse(xhr.responseText)
console.log(response)
}
}
xhr.send()
这里我的url写的是http://192.168.253.128:8000/user_info,是因为我的虚拟机的IP地址是这个、
从onreadystatechange的外部进行数据处理的办法
这个javascrpt代码无法将接收到的数据立即传递出,导致无法从onreadystatechange外面获得网页的值,要使用如下的javascript代码
//用于获取数据的函数,url是我们所要访问的网址
function getData(url, callback) {
let xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200)
callback(JSON.parse(xhr.responseText))
else
callback(null)
}
xhr.send()
}
//用于处理数据的函数,我这里是模拟登录
function handleResponse(response) {
if(response)
{
let username=document.getElementById("username").value
let password=document.getElementById("password").value
for(let user in response)
{
if(username===response[user][0])
if(password===response[user][1])
{
alert('登陆成功')
return
}
else {
alert('密码错误')
return
}
}
alert('无该用户')
}
else
return null
}
//登陆的函数,调用getData函数,并且callback的值是处理回复的函数名
function Login() {
getData("http://192.168.253.128:8000/user_info",handleResponse)
}
2.同步get到API的响应
向上面这样写是异步获取服务端的数据,比较麻烦
可以使用如下来同步获取,不等待服务器响应
主要不同是将xhr.open('GET', url, true)中的true改为了false,方便了许多
let xhr = new XMLHttpRequest()
xhr.open('GET', "http://192.168.253.128:8000/user_info/", false)
xhr.send(null)
let userData = JSON.parse(xhr.responseText)
function Login() {
let username = document.getElementById("username").value
let password = document.getElementById("password").value
for (let user in userData) {
if (username === userData[user][0])
if (password === userData[user][1]) {
alert('登陆成功')
return
} else {
alert('密码错误')
return
}
}
alert('用户不存在')
}
这是登陆界面的js代码
下面是注册界面的js代码(异步完成的话,服务端的数据库的base_info必须要设置主键,否则会重复插入)
这是异步,和登陆界面的异步十分相似,只是修改了handleReponse部分的代码
function Register() {
getData("http://192.168.253.128:8000/user_info", handleResponse)
}
function getData(url, callback) {
let xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
callback(JSON.parse(xhr.responseText))
} else
callback(null)
}
xhr.send(null)
}
function handleResponse(response) {
if (response) {
let username = document.getElementById("username").value
let password = document.getElementById("password").value
let password_again = document.getElementById("password_again").value
for (let user in response)
if (username === response[user][0]) {
alert('用户已存在')
return
}
if (password !== password_again) {
alert("两次输入的密码不一致")
return
}
alert("注册成功")
}
}
这是同步的,和登陆的很像,改了一下函数而已
let xhr = new XMLHttpRequest()
xhr.open('GET', "http://192.168.253.128:8000/user_info/", false)
xhr.send(null)
let userData = JSON.parse(xhr.responseText)
function Register() {
let username = document.getElementById("username").value
let password = document.getElementById("password").value
let password_again = document.getElementById("password_again").value
for (let user in userData)
if (username === userData[user][0]) {
alert('用户已存在')
return false
}
if (password !== password_again) {
alert("两次输入的密码不一致")
return false
}
alert("注册成功")
return true
}
这是完整代码
异步:
1.登录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
<script>
function Login() {
getData("http://192.168.253.128:8000/user_info", handleResponse)
}
function getData(url, callback) {
let xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
callback(JSON.parse(xhr.responseText))
} else
callback(null)
}
xhr.send(null)
}
function handleResponse(response) {
if (response) {
let username = document.getElementById("username").value
let password = document.getElementById("password").value
for (let user in response) {
if (username === response[user][0])
if (password === response[user][1]) {
alert('登陆成功')
return
} else {
alert('密码错误')
return
}
}
alert('用户不存在')
} else
return null
}
</script>
</head>
<body>
<form onclick="return false">
<input type="text" name="username" id="username"><br>
<input type="password" name="password" id="password"><br>
<input type="submit" value="登录" onclick="Login()">
</form>
</body>
</html>
2.注册
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<script>
function Register() {
getData("http://192.168.253.128:8000/user_info", handleResponse)
}
function getData(url, callback) {
let xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
callback(JSON.parse(xhr.responseText))
} else
callback(null)
}
xhr.send(null)
}
function handleResponse(response) {
if (response) {
let username = document.getElementById("username").value
let password = document.getElementById("password").value
let password_again = document.getElementById("password_again").value
for (let user in response)
if (username === response[user][0]) {
alert('用户已存在')
return
}
if (password !== password_again) {
alert("两次输入的密码不一致")
return
}
alert("注册成功")
}
}
</script>
<body>
<iframe id="id_iframe" name="nm_iframe" style="display:none;"></iframe>
<!--下面form表格的target方法是为了防止跳转-->
<!--这里和同步有区别,同步的提交方法在form标签里,这个在input标签里-->
<form action="http://192.168.253.128:8000/write_user/" method="post" target="nm_iframe">
<input type="text" name="username" id="username"><br>
<input type="password" name="password" id="password"><br>
<input type="password" name="password_again" id="password_again"><br>
<input type="submit" value="提交" onclick="Register()">
</form>
</body>
</html>
存在问题:无法在数据库不设置主键的情况下使用异步来阻断submit的重复提交
同步
1.登录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
<script>
let xhr = new XMLHttpRequest()
xhr.open('GET', "http://192.168.253.128:8000/user_info/", false)
xhr.send(null)
let userData = JSON.parse(xhr.responseText)
function Login() {
let username = document.getElementById("username").value
let password = document.getElementById("password").value
for (let user in userData) {
if (username === userData[user][0])
if (password === userData[user][1]) {
alert('登陆成功')
return
} else {
alert('密码错误')
return
}
}
alert('用户不存在')
}
</script>
</head>
<body>
<form onclick="return false">
<input type="text" name="username" id="username"><br>
<input type="password" name="password" id="password"><br>
<input type="submit" value="登录" onclick="Login()">
</form>
</body>
</html>
2.注册
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<script>
let xhr = new XMLHttpRequest()
xhr.open('GET', "http://192.168.253.128:8000/user_info/", false)
xhr.send(null)
let userData = JSON.parse(xhr.responseText)
function Register() {
let username = document.getElementById("username").value
let password = document.getElementById("password").value
let password_again = document.getElementById("password_again").value
for (let user in userData)
if (username === userData[user][0]) {
alert('用户已存在')
return false
}
if (password !== password_again) {
alert("两次输入的密码不一致")
return false
}
alert("注册成功")
return true
}
</script>
<body>
<iframe id="id_iframe" name="nm_iframe" style="display:none;"></iframe>
<!--下面form表格的target方法是为了防止跳转-->
<!--这里的onsubmit方法是为了防止注册的时候存在用户任然提交,虽然数据库设置主键可以解决,但是这样更好,双重保障嘛,异步我解决不了,麻烦哪位大神帮个忙-->
<form action="http://192.168.253.128:8000/write_user/" method="post" target="nm_iframe" onsubmit="return Register()">
<input type="text" name="username" id="username"><br>
<input type="password" name="password" id="password"><br>
<input type="password" name="password_again" id="password_again"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
【注意】我这里的数据库只有username和password所以我用了userData[user][0]来代表username,userData[user][1]来代替password
我现在只学了一点点皮毛,这篇博客主要是为了能够让自己记住哒