React+wangEditor V4富文字編輯器+Node.js實現圖像上傳

1、安裝wangeditor 4.6.15:

2、editor.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import React, { Component } from 'react'
import { Button, Space } from "antd"
import E from 'wangeditor'

export default class Editor extends Component {
    state = {
        content: ""
    }

    editor = {};

    // 取得html方法1
    getHtml = () => {
        alert(this.state.content)
    }

    // 取得html方法2
    getHtml1 = () => {
        alert(this.editor.txt.html())
    }

    // 取得text
    getText = () => {
        alert(this.editor.txt.text())
    }

    componentWillUnmount() {
        this.editor.destroy()
    }

    componentDidMount() {
        this.editor = new E(document.getElementById("wangeditor"));

        // 上傳圖像
        this.editor.config.uploadImgServer = '/api/upload';
        this.editor.config.uploadFileName = 'myFileName'; // ================這裡是關鍵,後台必須和這裡保持一致================
        this.editor.config.showLinkImg = false;
        this.editor.config.uploadImgTimeout = 60 * 1000;

        this.editor.config.uploadImgHooks = {
            // 上傳圖像之前
            before: function (xhr) {
                // console.log(xhr)

                // 可阻止圖像上傳
                // return {
                //     prevent: true,
                //     msg: '需要提示給使用者的錯誤訊息'
                // }
            },
            // 圖像上傳並回傳了結果,圖像寫入已成功
            success: function (xhr) {
                console.log('success', xhr)
            },
            // 圖像上傳並回傳了結果,但圖像寫入時出錯了
            fail: function (xhr, editor, resData) {
                console.log('圖像上傳並回傳了結果,但圖像寫入時出錯了')
                console.log(resData)
            },
            // 上傳圖像出錯,一般為 http 請求的錯誤
            error: function (xhr, editor, resData) {
                console.log('上傳圖像出錯,一般為 http 請求的錯誤')
                console.log('error', xhr, resData)
            },
            // 上傳圖像超時
            timeout: function (xhr) {
                console.log('timeout')
            },
            // 圖像上傳並回傳了結果,想要自己把圖像寫入到編輯器中
            // 例如伺服端回傳的不是 { errno: 0, data: [...] } 這種格式,可使用 customInsert
            customInsert: function (insertImg, result) {
                // result 即伺服端回傳的介面
                console.log('customInsert', result)
                console.log('customInsert')
                console.log(result)

                //var c = result.data[0].imgPath
                insertImg(insertImg);
                //insertImg("https://x0.ifengimg.com/res/2021/21921B99567A8C981CD0503086C2956B68888571_size381_w1200_h856.jpeg") //根據回傳的圖像路徑,將圖像寫入到頁面中,回顯
            }
        }

        /**一定要建立 */
        this.editor.create()

        this.editor.txt.html('<p><center>[wp_ad_camp_2]</center></p><p>用 JS 設定的內容</p>') // 重新設定編輯器內容
    }

    render() {
        return (
            <div>
                <div id="wangeditor"></div>
                <Space>
                    <Button type="primary" onClick={() => this.getHtml()}>取得html方法1</Button>
                    <Button type="primary" onClick={() => this.getHtml1()}>取得html方法2</Button>
                    <Button type="primary" onClick={() => this.getText()}>取得text方法</Button>
                </Space>
            </div>
        )
    }
}

其中:

1
2
this.editor.config.uploadImgServer = '/api/upload';
this.editor.config.uploadFileName = 'myFileName'; // 這裡是關鍵,後台必須和這裡保持一致

是關鍵

3、node.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const express = require("express")
const fs = require("fs")
const mysql = require("mysql")
const util = require("util")
const { getNow } = require("./tool")

const app = express();

var multer = require('multer');//獲得中介軟體
var upload = multer({dest:'uploads/'});//指定配置項,這裡指定檔案儲存於當前目錄下的upload子目錄
app.use(upload.single('myFileName'));//運用中介軟體,並且指明檔名,此名需要同html input name的檔名一致,否則會報錯

const bodyParser = require("body-parser");
const { nextTick } = require("process");
app.use("/static/", express.static("./static/"));
app.use('/node_modules/', express.static('./node_modules/'));
app.engine("html", require("express-art-template"))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

// 渲染頁面
app.get("/index", (req, res) => {
    res.render("index.html");
})

app.post("/api/upload", (req, res) => {
    res.jsonp({
        ret: false,
        total: 0,
        rows: [],
        msg: ""
    });
})


app.get("/404", (req, res) => {
    res.render("404.html");
})

// 配置一個全域拋錯與例外處理中介軟體
app.use(function (err, req, res, next) {
    res.status(500).json({
        err_code: 500,
        message: err.message
    })
})

app.listen(5555, () => {
    console.log("服務啟動成功......");
})

其中:

1
app.use(upload.single('myFileName'));//運用中介軟體,並且指明檔名,此名需要同html input name的檔名一致,否則會報錯
1
2
3
4
5
6
7
8
app.post("/api/upload", (req, res) => {
    res.jsonp({
        ret: false,
        total: 0,
        rows: [],
        msg: ""
    });
})

是關鍵。

wangEditorV4官網:https://www.wangeditor.com/