OSS上傳圖片無法在線預覽的解決方案


OSS上傳圖片無法在線預覽的解決方案


最近在做的項目涉及到商品詳情,由於前端用的flutter框架並且該詳情為富文本,dart語言關於富文本的組件不是非常友好,當富文本中的圖片無法在瀏覽器中直接預覽的時候(有時提示為下載鏈接),富文本組件無法顯示。


先記錄一下踩過的坑: 富文本中的圖片也需要相應的服務器進行存儲,否則會直接轉化成十六進制碼存放在數據庫中,如果圖片尺寸很大,尤其像商品詳情那樣的長圖來說,不管是存儲還是網絡傳輸,都是非常消耗性能的,所以富文本中的圖片也需要上傳至服務器。我的后台管理系統使用的是的react框架,用到的一款富文本編輯組件是wangeditor,該組件可以設置嵌套圖片的上傳路徑以及大小限制,非常方便,推薦使用。

下列是我的后台管理系統自己封裝的富文本組件:

import React from 'react';
import PropTypes from 'prop-types';
import { noop, get } from 'lodash';
import E from 'wangeditor';
import { message } from 'antd';
import CustomConfig from '../../../../env'
import {getToken} from "../../../../utils/authority";

export class RichTextEditor extends React.Component {
  componentDidMount() {
    const { value, onChange } = this.props;
    const elem = this.editor;
    const editor = new E(elem);
    this.configUploadPic(editor);
    // 使用 onchange 函數監聽內容的變化,並實時更新到 state 中
    editor.customConfig.onchange = html => {
      onChange(html);
    };
    editor.create();
    editor.txt.html(value);
  }

  configUploadPic = editor => {
    editor.customConfig.uploadImgServer = CustomConfig.BASE_URL + '/api/file/upload_embed_image';
    editor.customConfig.uploadImgHeaders = {
      //添加token
      authorization: getToken(),
    };
    editor.customConfig.uploadImgMaxSize = 5 * 1024 * 1024; // 圖片大小限制5M
    editor.customConfig.uploadImgMaxLength = 1; //一次最多一張圖片
    editor.customConfig.uploadImgTimeout = 25000; //25秒超時
    editor.customConfig.uploadFileName = 'file';
    editor.customConfig.customAlert = function(info) {
      // info 是需要提示的內容
      console.log(info);
    };
    editor.customConfig.uploadImgHooks = {
      error: function(xhr, editor) {
        // 圖片上傳出錯時觸發
        // xhr 是 XMLHttpRequst 對象,editor 是編輯器對象
        message.error(`圖片上傳失敗,${get(xhr, ['responseText'])}`);
      },
      timeout: function(xhr, editor) {
        // 圖片上傳超時時觸發
        // xhr 是 XMLHttpRequst 對象,editor 是編輯器對象
        message.error(`圖片上傳超時!`);
      },

      // 如果服務器端返回的不是 {errno:0, data: [...]} 這種格式,可使用該配置
      // (但是,服務器端返回的必須是一個 JSON 格式字符串!!!否則會報錯)
      customInsert: function(insertImg, result, editor) {
        // 圖片上傳並返回結果,自定義插入圖片的事件(而不是編輯器自動插入圖片!!!)
        // insertImg 是插入圖片的函數,editor 是編輯器對象,result 是服務器端返回的結果

        // 舉例:假如上傳圖片成功后,服務器端返回的是 {url:'....'} 這種格式,即可這樣插入圖片:
        const url = result.url;
        insertImg(url);
        // result 必須是一個 JSON 格式字符串!!!否則報錯
      },
    };
  };

  render() {
    return (
      <div
        ref={ref => {
          this.editor = ref;
        }}
      />
    );
  }
}

RichTextEditor.protoType = {
  value: PropTypes.string,
  onChange: PropTypes.func,
};

RichTextEditor.defaultProps = {
  value: '',
  onChange: noop,
};

順便提一下,lodash是一款非常方便、高效的集合處理工具,推薦使用。

回到正題

由於我使用的是阿里提供的OSS對象存儲,我在網上查找了相關的資料,都找不到相應的解決方案,最后查看了官方的開發文檔,設置Content-type之后終於得到解決,下面是相關代碼(使用kotlin):

    private fun MultipartFile.savePic(folderName:String = "pic"):String {
        fun getExtension(): String {
            val extension = this.originalFilename.orEmpty().substringAfterLast(".", "")
            return if (extension.isEmpty()) {
                ""
            } else
                ".$extension"
        }

        // 添加 ContentType (添加后可在瀏覽器中直接瀏覽,而非下載鏈接)
        val objectMetadata = ObjectMetadata()
        objectMetadata.contentType = "image/jpg"

        val objName = "$folderName/${UUID.randomUUID()}${getExtension()}"
        try {
            ossClient.putObject(bucketName, objName, this.inputStream, objectMetadata)
        } catch (e: Exception) {
            logger.error("上傳圖片失敗", e)
            throw BadRequestException("上傳圖片失敗")
        }
        return objName
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM