一、概述
为啥需要跨域处理,通常我们的API一般是给到前端去调用,但是前端可能使用域名和没提供的API域名是不一样,这就引发了浏览器同源策略问题,所以我们需要做跨域请求支持。
FastAPI支持跨域的话,可以通过添加中间的形式,和bottle也有相似之处。不仅如此他还支持仅限于支持哪些域名进行跨域请求:
import uvicorn from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() origins = [ "http://localhost.tiangolo.com", "https://localhost.tiangolo.com", "http://localhost", "http://localhost:8080", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def main(): return {"message": "Hello World"} if __name__ == '__main__': uvicorn.run(app='main:app', host="0.0.0.0", port=8000, reload=True, debug=True)
二、演示跨域
环境说明:
前端:
操作系统:centos 7.6
ip地址:192.168.31.35
运行软件:nginx
后端:
操作系统:windows 10
ip地址:192.168.31.61
运行软件:pycharm
请求api
登录到前端服务器,安装nginx,并启动。
yum install -y nginx
nginx
访问默认页面
http://192.168.31.35/
测试页面
登录到前端服务器,默认的nginx页面目录为:/usr/share/nginx/html
新建一个测试文件
cd /usr/share/nginx/html
vi test.html
内容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body> <button id="api">请求接口</button> <h4>结果</h4> <div id="content"></div> <script> $('#api').click(function () { $.ajax({ //发送ajax请求 url: 'http://192.168.31.61:8000/', type: "get", data: {}, success: function (arg) { //arg = JSON.parse(arg); console.log(arg); $('#content').text(arg.message) //return false; }, error: function () { console.log("网络请求错误!"); } }); }); </script> </body> </html>
访问测试页面
http://192.168.31.35/test.html
点击请求接口按钮,提示跨域。
为什么会出现跨域呢?因为同源策略。
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以192.168.31.35下的js脚本采用ajax读取192.168.31.61里面的文件数据是会被拒绝的。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
三、解决跨域
一般解决跨域,是在后端完成的,设置允许跨域。
修改main.py,增加前端的url地址即可。
import uvicorn from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() # 前端页面url origins = [ "http://localhost.tiangolo.com", "https://localhost.tiangolo.com", "http://localhost", "http://localhost:8080", "http://192.168.31.35", ] # 后台api允许跨域 app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def main(): return {"message": "Hello World"} if __name__ == '__main__': uvicorn.run(app='main:app', host="0.0.0.0", port=8000, reload=True, debug=True)
再次点击按钮,结果就会显示出来了。
本文参考链接: