0


20240303Uniapp前端从Fastapi后端读取图片

在后端服务器准备一张图

把基本的后端写好,这里的CORS中间件给全过了,因为就是我本机试一试,如果上生产环境有安全需求就不会全过了。

这是现在/返回的json。

我要把图片转成base64,加在这个json里面。

这是现在的前端script

  1. <script>
  2. export default {
  3. data() {
  4. return {
  5. message: '', // 用于存放从后端获取的消息
  6. good2:'',
  7. };
  8. },
  9. onLoad() {
  10. this.fetchData();
  11. },
  12. methods: {
  13. fetchData() {
  14. uni.request({
  15. url: 'http://127.0.0.1:8000/', // 你的FastAPI服务器地址
  16. method: 'GET',
  17. success: (res) => {
  18. console.log('请求成功:', res);
  19. this.message = res.data.message; // 将获取的消息存放到data的message中
  20. this.good2=res.data.商品2
  21. },
  22. fail: (err) => {
  23. console.error('请求失败:', err);
  24. }
  25. });
  26. }
  27. }
  28. }
  29. </script>

base64传输图片

然后现在我修改后端代码

  1. from fastapi import FastAPI
  2. from fastapi.middleware.cors import CORSMiddleware
  3. import base64
  4. app = FastAPI()
  5. # 添加CORS中间件
  6. app.add_middleware(
  7. CORSMiddleware,
  8. allow_origins=["*"], # 允许所有来源,为了安全起见,你应该限制为你的前端应用的实际来源
  9. allow_credentials=True,
  10. allow_methods=["*"], # 允许所有方法
  11. allow_headers=["*"], # 允许所有头
  12. )
  13. @app.get("/")
  14. async def root():
  15. image_path=('./image/my_favourite_fll.jpg')
  16. with open(image_path, "rb") as image_file:
  17. encoded_image = base64.b64encode(image_file.read()).decode('utf-8')
  18. return {"message": "商品1","商品2":"超级无敌大光波","image_path":encoded_image}

现在return的json加上了图片的base64,看一看

相当吓人,这只是一张35KB的图,难怪要想一些压缩算法减少图片大小,10M带宽一秒不过传输一个用户一张1.25MB的图片。不过数据传输优化的问题后面再说。

我先搞定这边传图。

前端增加读取代码,我这里就不给出我项目前端的其他代码了

  1. <template>
  2. <view>
  3. <image :src="imageSrc" mode="aspectFit" style="width: 300px; height: 200px;"></image>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. data() {
  9. return {
  10. imageSrc: '', // 存储图片的Base64编码
  11. };
  12. },
  13. onLoad() {
  14. this.fetchImage();
  15. },
  16. methods: {
  17. fetchImage() {
  18. uni.request({
  19. url: 'http://your-server.com/image', // 更改为你的API地址
  20. method: 'GET',
  21. success: (res) => {
  22. this.imageSrc = 'data:image/jpeg;base64,' + res.data.image; // 设置图片的Base64编码
  23. },
  24. fail: (err) => {
  25. console.error('请求图片失败:', err);
  26. },
  27. });
  28. },
  29. },
  30. };
  31. </script>
  1. data:image/jpeg;base64,

后跟图片的Base64编码可以作为图片资源的地址使用。这种格式的字符串通常称为“数据URL”(data URLs),它允许你将图片或其他文件类型直接嵌入到网页中,而不是通过传统的文件路径或URL地址来引用资源。

数据URL的基本格式如下:

  1. data:[<mediatype>][;base64],<data>
  • <mediatype> 是数据的MIME类型,对于JPEG图片,这里就是image/jpeg
  • ;base64 指示随后的数据是以Base64编码的。
  • <data> 是实际的数据,对于图片来说,就是图片文件的Base64编码内容。

例子

  1. <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDAAoHBwkHBgoJCAkLCwoMDxkQDw4ODx4WFxIZJCAmJSMgIyIoLTkwKCo2KyIjMkQyNjs9QEBAJjBGS0U+Sjk/QD3/2wBDAQsLCw8NDx0QEB09KSMpPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT3/wAARCAABA...(此处省略了实际的Base64编码)..." alt="示例图片">

将图片以Base64编码的形式嵌入到网页中的好处包括:

  • 减少了HTTP请求的数量,因为图片内容直接嵌入在HTML中,不需要额外的请求去加载图片。
  • 在一些特定场景下(如电子邮件客户端不允许外部资源加载)非常有用。

然而,使用数据URL也有一些潜在的缺点:

  • Base64编码的数据比原始的二进制数据大约增加33%,这会增加页面的大小,从而可能影响加载时间和带宽使用。
  • 大量使用Base64编码的图片可能会增加浏览器的内存使用量。
  • 对于较大的图片,使用外部链接可能更高效,因为浏览器可以缓存这些图片,而Base64编码的图片每次都需要随页面一起加载。

因此,是否使用Base64编码的图片作为资源地址需要根据具体的应用场景和性能需求来决定。对于小图标或一些不经常变化的小图片,使用数据URL可以是一个好的选择。对于较大的图片,可能还是传统的图片URL更加合适。

这里要说明如果用uniapp打包客户端app给用户用,那么运行起来,你后端传的url得是外部url,通向你服务器图片的,可别写用户本地的url了。这点和网页不同,动态网页是SSR服务器渲染,前端也运行在服务器上,url是服务器内部的。

冒号的作用

  1. <image src={{imageSrc}} class='pic' mode="aspectFit"></image>

是不可以的.

在使用 uni-app 开发时,其模板语法遵循 Vue.js 的标准。因此,当你想要在

  1. <image>

组件中绑定图片源 (

  1. src

) 到一个动态变量时,你应该使用

  1. v-bind:src

或简写为

  1. :src

来实现。所以,如果你有一个变量

  1. imageSrc

存储了图片的URL或Base64编码,你应该这样写:

  1. <image :src="imageSrc" class="pic" mode="aspectFit"></image>

这种方式告诉 Vue (以及 uni-app),

  1. src

属性的值是一个 JavaScript 表达式,即变量

  1. imageSrc

的当前值。这样,无论

  1. imageSrc

何时更新,Vue 都会自动更新 DOM 中的

  1. <image>

元素的

  1. src

属性。

写法

  1. src={{imageSrc}}

更接近于 Angular 或某些模板引擎的语法。在 Vue 和 uni-app 中,你应该使用

  1. v-bind

指令或其简写

  1. :

来绑定动态属性。

然后就OK啦

下一期:

过程中我发现CORS中间件是为了安全需求而存在的,但是我的uniapp生成的app客户端来自各个手机,我只要限制请求后端的应用而不限制设备,如何操作呢?

前端设置头 header json,里面来一个密码属性

  1. uni.request({
  2. url: 'http://your-backend-api.com/endpoint',
  3. method: 'GET',
  4. header: {
  5. 'X-App-Secret': 'your_secret_key'
  6. },
  7. success: function (res) {
  8. console.log(res.data);
  9. }
  10. });

后端检查这个密码属性。如果不是就raise HTTPException(status_code=400, detail="Invalid App Secret")

  1. from fastapi import FastAPI, Header, HTTPException
  2. app = FastAPI()
  3. @app.get("/endpoint")
  4. async def read_endpoint(x_app_secret: str = Header(None)):
  5. if x_app_secret != "your_secret_key":
  6. raise HTTPException(status_code=400, detail="Invalid App Secret")
  7. return {"message": "Success"}
  1. raise HTTPException(status_code=400, detail="Invalid App Secret")
  1. raise

是Python中用来触发异常的关键字。

  1. HTTPException

是一个特定类型的异常,通常在Web框架(如FastAPI)中使用,用于表示HTTP请求过程中出现的错误。

  • status_code=400 指定了HTTP状态码为400。HTTP状态码400通常表示客户端错误,具体来说,它表示请求由于语法错误而无法被服务器理解。在这种情况下,使用400状态码意味着服务器认为客户端发送的请求在某种程度上是错误的或不合理的。
  • detail="Invalid App Secret" 是提供给客户端的错误详情,这里说明了出错的具体原因。在这个例子中,错误的详情是“Invalid App Secret”,意味着请求中提供的应用密钥(App Secret)无效或不正确。

将这两部分结合起来,

  1. raise HTTPException(status_code=400, detail="Invalid App Secret")

这行代码的作用是:当遇到某些条件(例如,一个API请求没有提供正确的应用密钥)时,服务器会中断当前的处理流程,返回一个状态码为400的HTTP响应给客户端,并在响应体中包含一个错误详情,说明错误的原因是“Invalid App Secret”。

这种做法是Web开发中处理和反馈客户端错误的一种常见方式,它帮助客户端开发者理解请求失败的原因,从而可以采取相应的修正措施。

标签: 前端 fastapi

本文转载自: https://blog.csdn.net/thestareye/article/details/136441044
版权归原作者 小仙童大王 所有, 如有侵权,请联系我们删除。

“20240303Uniapp前端从Fastapi后端读取图片”的评论:

还没有评论