1 year ago
#369595
楊嘉翔
react-quill quill-upload _onUpload to API sometimes notWorking
I use React-Quill、quill-upload、Aixos、express
post image to API,but sometimes image address is true ,sometimes is flase
MySQL QuillContent
Nice Post Show Nice Post, Bad Post Show Bad Post=>The difference is iamgeColor
Upload image Regardless of success or failure,Server side have been stored image
./CreatePost
<div style={{ paddingTop: "20px" }}>
<h3 style={{ paddingBottom: "10px" }}>輸入內容</h3>
<EditorToolbar />
<ReactQuill
theme="snow"
value={content}
onChange={setContent}
modules={modules}
/>
</div>
./EditorToolbar
import React from "react";
import { Quill } from "react-quill";
import ResizeModule from "@botom/quill-resize-module";
import axios from "axios";
import { ImageHandler, VideoHandler, AttachmentHandler } from "quill-upload";
const config = require('../../config/default.json')
const apiURL = config.apiURL;
//提供Quill套件image、video改變大小用
Quill.register("modules/resize", ResizeModule);
Quill.register("modules/imageHandler", ImageHandler);
Quill.register("modules/videoHandler", VideoHandler);
Quill.register("modules/attachmentHandler", AttachmentHandler);
// Custom Undo button icon component for Quill editor. You can import it directly
// from 'quill/assets/icons/undo.svg' but I found that a number of loaders do not
// handle them correctly
const CustomUndo = () => (
<svg viewBox="0 0 18 18">
<polygon className="ql-fill ql-stroke" points="6 10 4 12 2 10 6 10" />
<path
className="ql-stroke"
d="M8.09,13.91A4.6,4.6,0,0,0,9,14,5,5,0,1,0,4,9"
/>
</svg>
);
// Redo button icon component for Quill editor
const CustomRedo = () => (
<svg viewBox="0 0 18 18">
<polygon
className="ql-fill ql-stroke"
points="12 10 14 12 16 10 12 10"
/>
<path
className="ql-stroke"
d="M9.91,13.91A4.6,4.6,0,0,1,9,14a5,5,0,1,1,5-5"
/>
</svg>
);
// Undo and redo functions for Custom Toolbar
function undoChange() {
this.quill.history.undo();
}
function redoChange() {
this.quill.history.redo();
}
// Add sizes to whitelist and register them
const Size = Quill.import("formats/size");
Size.whitelist = ["extra-small", "small", "medium", "large"];
Quill.register(Size, true);
// Add fonts to whitelist and register them
const Font = Quill.import("formats/font");
Font.whitelist = [
"arial",
"comic-sans",
"courier-new",
"georgia",
"helvetica",
"lucida",
];
Quill.register(Font, true);
// Modules object for setting up the Quill editor
export const modules = {
toolbar: {
container: "#toolbar",
handlers: {
undo: undoChange,
redo: redoChange,
},
},
history: {
delay: 500,
maxStack: 100,
userOnly: true,
},
resize: {
locale: {
// 圖片、影片調整大小以及定位功能
altTip: "Hold down the alt key to zoom",
floatLeft: "Left",
floatRight: "Right",
center: "Center",
restore: "Restore",
},
},
videoHandler: {
upload: (file) => {
// return a Promise that resolves in a link to the uploaded image
return new Promise((resolve) => {
const fd = new FormData();
fd.append("video", file);
_onUpload(fd, resolve,'video');
});
},
},
imageHandler: {
upload: (file) => {
return new Promise((resolve,reject) => {
const fd = new FormData();
fd.append("image", file);
_onUpload(fd, resolve,'image');
});
},
},
};
// Formats objects for setting up the Quill editor
export const formats = [
"header",
"font",
"size",
"bold",
"italic",
"underline",
"align",
"strike",
"script",
"blockquote",
"background",
"list",
"bullet",
"indent",
"link",
"image",
"video",
"color",
"code-block",
];
// Quill Toolbar component
export const QuillToolbar = () => (
<div id="toolbar">
<span className="ql-formats">
<select className="ql-font" defaultValue="arial">
<option value="arial">Arial</option>
<option value="comic-sans">Comic Sans</option>
<option value="courier-new">Courier New</option>
<option value="georgia">Georgia</option>
<option value="helvetica">Helvetica</option>
<option value="lucida">Lucida</option>
</select>
<select className="ql-size" defaultValue="medium">
<option value="extra-small">Size 1</option>
<option value="small">Size 2</option>
<option value="medium">Size 3</option>
<option value="large">Size 4</option>
</select>
<select className="ql-header" defaultValue="3">
<option value="1">Heading</option>
<option value="2">Subheading</option>
<option value="3">Normal</option>
</select>
</span>
<span className="ql-formats">
<button className="ql-bold" />
<button className="ql-italic" />
<button className="ql-underline" />
<button className="ql-strike" />
</span>
<span className="ql-formats">
<button className="ql-list" value="ordered" />
<button className="ql-list" value="bullet" />
<button className="ql-indent" value="-1" />
<button className="ql-indent" value="+1" />
</span>
<span className="ql-formats">
<button className="ql-script" value="super" />
<button className="ql-script" value="sub" />
<button className="ql-blockquote" />
<button className="ql-direction" />
</span>
<span className="ql-formats">
<select className="ql-align" />
<select className="ql-color" />
<select className="ql-background" />
</span>
<span className="ql-formats">
<button className="ql-link" />
<button className="ql-image" />
<button className="ql-video" />
</span>
<span className="ql-formats">
<button className="ql-formula" />
<button className="ql-code-block" />
<button className="ql-clean" />
</span>
<span className="ql-formats">
<button className="ql-undo">
<CustomUndo />
</button>
<button className="ql-redo">
<CustomRedo />
</button>
</span>
</div>
);
const _onUpload = async (fd, resolve,type) => {
axios.defaults.withCredentials = true;
const result =
await axios.post(
`${apiURL}/api/upload/${type}`,fd
)
.catch(err=>console.log(err));
resolve(`http://localhost:3090/${type}/${result.data.fileName}`);
};
export default QuillToolbar;
Our Back-end developer After update ./NodeJS(expross) Nothing error Message
require('dotenv').config()
const express = require('express')
const app = express()
const cors = require('cors')
const cookieParser = require('cookie-parser')
const fileUpload = require('express-fileupload')
const APIRouter = require('./routes/api')
const { router: authRouter } = require('./routes/auth')
const port = process.env.PORT
app.use(express.json({ limit: '50mb' }))
app.use(express.urlencoded({ extended: true, limit: '50mb' }))
app.use(cors({ credentials: true, origin: process.env.WEB_ORIGIN_URL }))
app.use(cookieParser())
app.use(fileUpload())
app.use(express.static('./public'))
app.use('/periodical/auth', authRouter)
app.use('/periodical/api', APIRouter)
app.listen(port, () => {
console.log(`Server is running at port ${port}`)
})
Our Back-end developer Before update ./NodeJS(expross) error message enter image description here
require('dotenv').config();
const express = require('express');
const app = express();
const cors = require('cors');
const cookieParser = require('cookie-parser');
const fileUpload = require('express-fileupload');
const APIRouter = require('./routes/api');
const { router: authRouter } = require('./routes/auth');
const port = process.env.PORT;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors({ credentials: true, origin: process.env.WEB_ORIGIN_URL }));
app.use(cookieParser());
app.use(fileUpload());
app.use(express.static('./public'));
app.use('/periodical/auth', authRouter);
app.use('/periodical/api', APIRouter);
app.listen(port, () => {
console.log(`Server is running at port ${port}`);
});
Nodejs./upload.js
const express = require('express');
const router = express.Router();
const path = require('path');
const util = require('util');
router.route('/video').post(async (req, res) => {
try {
const file = req.files.video;
const extension = path.extname(file.name);
if (file.size > 100000000) return res.status(400).json({ message: 'File must be less than 100MB' });
if (file) {
const fileName = file.md5 + extension;
const URL = `./public/video/${fileName}`;
await util.promisify(file.mv)(URL);
return res.status(200).json({ message: 'Video uploaded successfully', fileName });
} else {
return res.status(400).json({ message: 'Lost video file' });
}
} catch (error) {
return res.status(500).json({ error });
}
});
router.route('/image').post(async (req, res) => {
try {
const file = req.files.image;
const extension = path.extname(file.name);
if (file.size > 100000000) return res.status(400).json({ message: 'File must be less than 100MB' });
if (file) {
const fileName = file.md5 + extension;
const URL = `./public/image/${fileName}`;
await util.promisify(file.mv)(URL);
return res.status(200).json({ message: 'Image uploaded successfully', fileName });
} else {
return res.status(400).json({ message: 'Lost image file' });
}
} catch (error) {
return res.status(500).json({ error });
}
});
module.exports = router;
node.js
reactjs
express
axios
react-quill
0 Answers
Your Answer