http://ueditor.baidu.com/build/build_down.php?n=ueditor&v=1_4_3_3-src
引入其他jar包
org.json
json
commons-fileupload
commons-fileupload
1.3.2
commons-codec
commons-codec
1.9
修改ConfigManager中的initEnv()方法为
private void initEnv () throws FileNotFoundException, IOException {
File file = new File( this.originalPath );
if ( !file.isAbsolute() ) {
file = new File( file.getAbsolutePath() );
}
this.parentPath = file.getParent();
// String configContent = this.readFile( this.getConfigPath() );
String configJsonPath = null;
try {
configJsonPath = this.getClass().getClassLoader().getResource("config.json").toURI().getPath();
} catch (URISyntaxException e) {
e.printStackTrace();
}
String configContent = this.readFile( configJsonPath );
try{
JSONObject jsonConfig = new JSONObject( configContent );
this.jsonConfig = jsonConfig;
} catch ( Exception e ) {
this.jsonConfig = null;
}
}
package com.XXX.cloud.platfrom.common.file.utils;
/**
* @Description: PublishMsg-config.json
* @ClassName: PublishMsg
* @Author: XXX
* @Date: 2019/12/24 14:14
* @Version: 1.0
*/
public class PublicMsg {
public static String UEDITOR_CONFIG = "{\n" +
" \"imageActionName\":\"uploadimage\",\n" +
" \"imageFieldName\":\"upfile\",\n" +
" \"imageMaxSize\":2048000,\n" +
" \"imageAllowFiles\":[\n" +
" \".png\",\n" +
" \".jpg\",\n" +
" \".jpeg\",\n" +
" \".gif\",\n" +
" \".bmp\"\n" +
" ],\n" +
" \"imageCompressEnable\":true,\n" +
" \"imageCompressBorder\":1600,\n" +
" \"imageInsertAlign\":\"none\",\n" +
" \"imageUrlPrefix\":\"\",\n" +
" \"imagePathFormat\":\"/storage/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
" \"scrawlActionName\":\"uploadscrawl\",\n" +
" \"scrawlFieldName\":\"upfile\",\n" +
" \"scrawlPathFormat\":\"/storage/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
" \"scrawlMaxSize\":2048000,\n" +
" \"scrawlUrlPrefix\":\"http://35.201.165.105:8000\",\n" +
" \"scrawlInsertAlign\":\"none\",\n" +
" \"snapscreenActionName\":\"uploadimage\",\n" +
" \"snapscreenPathFormat\":\"/storage/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
" \"snapscreenUrlPrefix\":\"http://35.201.165.105:8000\",\n" +
" \"snapscreenInsertAlign\":\"none\",\n" +
" \"catcherLocalDomain\":[\n" +
" \"127.0.0.1\",\n" +
" \"localhost\",\n" +
" \"img.baidu.com\"\n" +
" ],\n" +
" \"catcherActionName\":\"catchimage\",\n" +
" \"catcherFieldName\":\"source\",\n" +
" \"catcherPathFormat\":\"/storage/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
" \"catcherUrlPrefix\":\"\",\n" +
" \"catcherMaxSize\":2048000,\n" +
" \"catcherAllowFiles\":[\n" +
" \".png\",\n" +
" \".jpg\",\n" +
" \".jpeg\",\n" +
" \".gif\",\n" +
" \".bmp\"\n" +
" ],\n" +
" \"videoActionName\":\"uploadvideo\",\n" +
" \"videoFieldName\":\"upfile\",\n" +
" \"videoPathFormat\":\"/storage/video/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
" \"videoUrlPrefix\":\"\",\n" +
" \"videoMaxSize\":102400000,\n" +
" \"videoAllowFiles\":[\n" +
" \".flv\",\n" +
" \".swf\",\n" +
" \".mkv\",\n" +
" \".avi\",\n" +
" \".rm\",\n" +
" \".rmvb\",\n" +
" \".mpeg\",\n" +
" \".mpg\",\n" +
" \".ogg\",\n" +
" \".ogv\",\n" +
" \".mov\",\n" +
" \".wmv\",\n" +
" \".mp4\",\n" +
" \".webm\",\n" +
" \".mp3\",\n" +
" \".wav\",\n" +
" \".mid\"\n" +
" ],\n" +
" \"fileActionName\":\"uploadfile\",\n" +
" \"fileFieldName\":\"upfile\",\n" +
" \"filePathFormat\":\"/storage/file/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
" \"fileUrlPrefix\":\"\",\n" +
" \"fileMaxSize\":51200000,\n" +
" \"fileAllowFiles\":[\n" +
" \".png\",\n" +
" \".jpg\",\n" +
" \".jpeg\",\n" +
" \".gif\",\n" +
" \".bmp\",\n" +
" \".flv\",\n" +
" \".swf\",\n" +
" \".mkv\",\n" +
" \".avi\",\n" +
" \".rm\",\n" +
" \".rmvb\",\n" +
" \".mpeg\",\n" +
" \".mpg\",\n" +
" \".ogg\",\n" +
" \".ogv\",\n" +
" \".mov\",\n" +
" \".wmv\",\n" +
" \".mp4\",\n" +
" \".webm\",\n" +
" \".mp3\",\n" +
" \".wav\",\n" +
" \".mid\",\n" +
" \".rar\",\n" +
" \".zip\",\n" +
" \".tar\",\n" +
" \".gz\",\n" +
" \".7z\",\n" +
" \".bz2\",\n" +
" \".cab\",\n" +
" \".iso\",\n" +
" \".doc\",\n" +
" \".docx\",\n" +
" \".xls\",\n" +
" \".xlsx\",\n" +
" \".ppt\",\n" +
" \".pptx\",\n" +
" \".pdf\",\n" +
" \".txt\",\n" +
" \".md\",\n" +
" \".xml\"\n" +
" ],\n" +
" \"imageManagerActionName\":\"listimage\",\n" +
" \"imageManagerListPath\":\"/storage/image/\",\n" +
" \"imageManagerListSize\":20,\n" +
" \"imageManagerUrlPrefix\":\"\",\n" +
" \"imageManagerInsertAlign\":\"none\",\n" +
" \"imageManagerAllowFiles\":[\n" +
" \".png\",\n" +
" \".jpg\",\n" +
" \".jpeg\",\n" +
" \".gif\",\n" +
" \".bmp\"\n" +
" ],\n" +
" \"fileManagerActionName\":\"listfile\",\n" +
" \"fileManagerListPath\":\"/storage/file/\",\n" +
" \"fileManagerUrlPrefix\":\"\",\n" +
" \"fileManagerListSize\":20,\n" +
" \"fileManagerAllowFiles\":[\n" +
" \".png\",\n" +
" \".jpg\",\n" +
" \".jpeg\",\n" +
" \".gif\",\n" +
" \".bmp\",\n" +
" \".flv\",\n" +
" \".swf\",\n" +
" \".mkv\",\n" +
" \".avi\",\n" +
" \".rm\",\n" +
" \".rmvb\",\n" +
" \".mpeg\",\n" +
" \".mpg\",\n" +
" \".ogg\",\n" +
" \".ogv\",\n" +
" \".mov\",\n" +
" \".wmv\",\n" +
" \".mp4\",\n" +
" \".webm\",\n" +
" \".mp3\",\n" +
" \".wav\",\n" +
" \".mid\",\n" +
" \".rar\",\n" +
" \".zip\",\n" +
" \".tar\",\n" +
" \".gz\",\n" +
" \".7z\",\n" +
" \".bz2\",\n" +
" \".cab\",\n" +
" \".iso\",\n" +
" \".doc\",\n" +
" \".docx\",\n" +
" \".xls\",\n" +
" \".xlsx\",\n" +
" \".ppt\",\n" +
" \".pptx\",\n" +
" \".pdf\",\n" +
" \".txt\",\n" +
" \".md\",\n" +
" \".xml\"\n" +
" ]\n" +
"}";
/**
* Ueditor的返回状态类型
*/
public enum UeditorMsg{
SUCCESS("SUCCESS"),ERROR("上传失败");
private String v;
UeditorMsg(String v){
this.v =v;
}
public String get(){
return this.v;
}
}
}
package com.xxx.cloud.platfrom.common.file.rest;
import com.xxx.cloud.common.base.rest.BaseController;
import com.xxx.cloud.common.storage.FileStorage;
import com.xxx.cloud.common.util.PatternConstants;
import com.xxx.cloud.platfrom.common.file.entity.FileDo;
import com.xxx.cloud.platfrom.common.file.model.vo.FileVo;
import com.xxx.cloud.platfrom.common.file.service.FileService;
import com.xxx.cloud.platfrom.common.file.utils.PublicMsg;
import com.google.common.collect.Maps;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Map;
/**
* @Description: Ueditor
* @ClassName: UeditorController
* @Author: xxx
* @Date: 2019/12/24 14:25
* @Version: 1.0
*/
@RestController
public class UeditorController extends BaseController {
private Logger logger = LoggerFactory.getLogger(getClass());
@Resource
private FileService fileService;
@Resource
private FileStorage fileStorage;
@RequestMapping("/ueditor/ueditorConfig")
public void ueditorConfig(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "upfile",required = false) MultipartFile upfile) {
logger.info("进入ueditorConfig===========");
response.setContentType("application/json;charset=utf-8");
String rootPath = request.getSession().getServletContext().getRealPath("/");
try {
String exec = null;
String actionType = request.getParameter("action");
if ("config".equals(actionType)) {
// 请求参数中的action若为"config",则标识此请求为获取富文本的config.json,且此请求为前端初始化富文本组件之后自动调用的
request.setCharacterEncoding( "utf-8" );
exec = PublicMsg.UEDITOR_CONFIG;
} else if (!upfile.isEmpty()) {
// 若action不是"config",则表示为上传文件操作,文件类型在config.json中都有体现
exec = uploadImage(upfile);
}
PrintWriter writer = response.getWriter();
writer.write(exec);
writer.flush();
writer.close();
} catch (IOException e) {
logger.error("UeditorController-->ueditorConfig exception:", e);
}
}
public String uploadImage(MultipartFile file) {
logger.info("进入上传.....ueditor");
InputStream inputStream = null;
FileDo fileDo = null;
try {
inputStream = file.getInputStream();
String originalFileName = file.getOriginalFilename();
String extension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
long fileSize = file.getSize();
String url = "";
String thumbImageUrl = "";
Integer width = 0;
Integer height = 0;
if(originalFileName.matches(PatternConstants.PHOTO)){
// 获取图片的宽和高
BufferedImage image = ImageIO.read(inputStream);
width = image.getWidth();
height = image.getHeight();
// 上传原图和缩略图
url = fileStorage.uploadImageAndCrtThumbImage(file);
thumbImageUrl = fileService.thumbImageUrl(url, null, null);
} else {
// 存储上传
url = fileStorage.uploadFile(inputStream , fileSize, originalFileName);
}
fileDo = new FileDo(originalFileName, url, thumbImageUrl, extension, fileSize, "ueditor", "ueditor", width, height);
} catch (IOException e) {
e.printStackTrace();
}
if (fileDo != null) {
FileVo fileVo = fileService.saveFile(fileDo);
return new JSONObject(resultMap("SUCCESS", fileVo.getUrl(), fileVo.getSize(), fileVo.getFileName(), fileVo.getFileName(), fileVo.getContentType())).toString();
} else {
return new JSONObject(resultMap("文件上传失败","",0,"","","")).toString();
}
}
// 返回前端的json格式,貌似富文本要求为此种格式,组件便与解析
private Map resultMap(String state, String url, long size, String title, String original, String type){
Map result = Maps.newHashMap();
result.put("state",state);
result.put("original",original);
result.put("size",size);
result.put("title",title);
result.put("type",type);
result.put("url", url);
return result;
}
}
{
//上传图片配置项
// 上传图片的action名称,与第一次请求config.json中的action=config一个意思
"imageActionName": "uploadimage",
// 上传图片的请求参数名称 @RequestParam("upfile")一个意思
"imageFieldName": "upfile",
// 上传图片的大小限制,富文本框会替我们检测
"imageMaxSize": 2048000,
// 支持上传的图片格式
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],
"imageCompressEnable": true,
"imageCompressBorder": 1600,
"imageInsertAlign": "none",
// 后端返回的图片url前缀,富文本会替我们自动拼接上,若后端返回的是完整地址,此处为空即可
"imageUrlPrefix": "",
"imagePathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
//涂鸦图片上传配置项
"scrawlActionName": "uploadscrawl",
"scrawlFieldName": "upfile",
"scrawlPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
"scrawlMaxSize": 2048000,
"scrawlUrlPrefix": "",
"scrawlInsertAlign": "none",
//截图工具上传
"snapscreenActionName": "uploadimage",
"snapscreenPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
"snapscreenUrlPrefix": "",
"snapscreenInsertAlign": "none",
//抓取远程图片配置
"catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
"catcherActionName": "catchimage",
"catcherFieldName": "source",
"catcherPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
"catcherUrlPrefix": "",
"catcherMaxSize": 2048000,
"catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],
// 视频action名称
"videoActionName": "uploadvideo",
"videoFieldName": "upfile",
"videoPathFormat": "/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}",
"videoUrlPrefix": "",
"videoMaxSize": 102400000,
"videoAllowFiles": [
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"],
//上传文件配置
"fileActionName": "uploadfile",
"fileFieldName": "upfile",
"filePathFormat": "/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}",
"fileUrlPrefix": "",
"fileMaxSize": 51200000,
"fileAllowFiles": [
".png", ".jpg", ".jpeg", ".gif", ".bmp",
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
],
//列出指定目录下的图片
"imageManagerActionName": "listimage",
"imageManagerListPath": "/ueditor/jsp/upload/image/",
"imageManagerListSize": 20,
"imageManagerUrlPrefix": "",
"imageManagerInsertAlign": "none",
"imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],//列出的文件类型
//列出指定目录下的文件
"fileManagerActionName": "listfile",//执行文件管理的action名称
"fileManagerListPath": "/ueditor/jsp/upload/file/",//指定要列出文件的目录
"fileManagerUrlPrefix": "",//文件访问路径前缀
"fileManagerListSize": 20,//每次列出文件数量
"fileManagerAllowFiles": [
".png", ".jpg", ".jpeg", ".gif", ".bmp",
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
]//列出的文件类型
}
配置项说明:(参考https://blog.csdn.net/taian1665/article/details/77859797)
1. 上传图片配置项
imageActionName {String} [默认值:"uploadimage"] //执行上传图片的action名称,
imageFieldName {String} [默认值:"upfile"] //提交的图片表单名称
imageMaxSize {Number} [默认值:2048000] //上传大小限制,单位B
imageAllowFiles {String} , //上传图片格式显示
//默认值:
[".png", ".jpg", ".jpeg", ".gif", ".bmp"]
imageCompressEnable {Boolean} [默认值:true] //是否压缩图片,默认是true
imageCompressBorder {Number} [默认值:1600] //图片压缩最长边限制
imageInsertAlign {String} [默认值:"none"] //插入的图片浮动方式
imageUrlPrefix {String} [默认值:""] //图片访问路径前缀
imagePathFormat {String} [默认值:"/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}"] //上传保存路径,可以自定义保存路径和文件名格式,上传路径配置
2. 涂鸦图片上传配置项
scrawlActionName {String} [默认值:"uploadscrawl"] //执行上传涂鸦的action名称
scrawlFieldName {String} [默认值:"upfile"] //提交的图片表单名称
scrawlPathFormat {String} [默认值:"/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}"] //上传保存路径,可以自定义保存路径和文件名格式,上传路径配置
scrawlMaxSize {Number} [默认值:2048000] //上传大小限制,单位B
scrawlUrlPrefix {String} [默认值:""] //图片访问路径前缀
scrawlInsertAlign {String} [默认值:"none"]
3. 截图工具上传
snapscreenActionName {String} [默认值:"uploadimage"] //执行上传截图的action名称
snapscreenPathFormat {String} [默认值:"/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}"] //上传保存路径,可以自定义保存路径和文件名格式,上传路径配置
snapscreenUrlPrefix {String} [默认值:""] //图片访问路径前缀
snapscreenInsertAlign {String} "none", //插入的图片浮动方式
4. 抓取远程图片配置
catcherLocalDomain {Array} 默认值:["127.0.0.1", "localhost", "img.baidu.com"]//例外的图片抓取域名
catcherActionName {String} [默认值:"catchimage"] //执行抓取远程图片的action名称
catcherFieldName {String} [默认值:"source"] //提交的图片列表表单名称
catcherPathFormat {String} [默认值:"/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}"] //上传保存路径,可以自定义保存路径和文件名格式,上传路径配置
catcherUrlPrefix {String} [默认值:""] //图片访问路径前缀
catcherMaxSize {Number} [默认值:2048000] //上传大小限制,单位B
catcherAllowFiles {Array}, //抓取图片格式显示
//默认值:
[".png", ".jpg", ".jpeg", ".gif", ".bmp"]
5. 上传视频配置
videoActionName {String} [默认值:"uploadvideo"] //执行上传视频的action名称
videoFieldName {String} [默认值:"upfile"] //提交的视频表单名称
videoPathFormat {String} [默认值:"/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}"] //上传保存路径,可以自定义保存路径和文件名格式,上传路径配置
videoUrlPrefix {String} [默认值:""] //视频访问路径前缀
videoMaxSize {Number} [默认值:102400000] //上传大小限制,单位B,默认100MB,注意修改服务器的大小限制
videoAllowFiles {Array}, //上传视频格式显示
//默认值:
[
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"
]
6. 上传文件配置
fileActionName {String} [默认值:"uploadfile"] //controller里,执行上传视频的action名称
fileFieldName {String} [默认值:"upfile"] //提交的文件表单名称
filePathFormat {String} [默认值:"/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}"] //上传保存路径,可以自定义保存路径和文件名格式,上传路径配置
fileUrlPrefix {String} [默认值:""] //文件访问路径前缀
fileMaxSize {Number} [默认值:51200000] //上传大小限制,单位B,默认50MB,注意修改服务器的大小限制
fileAllowFiles {Array}, //上传文件格式显示
//默认值:
[
".png", ".jpg", ".jpeg", ".gif", ".bmp",
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
]
7. 列出指定目录下的图片
imageManagerActionName {String} [默认值:"listimage"] //执行图片管理的action名称
imageManagerListPath {String} [默认值:"/ueditor/php/upload/image/"] //指定要列出图片的目录
imageManagerListSize {String} [默认值:20] //每次列出文件数量
imageManagerUrlPrefix {String} [默认值:""] //图片访问路径前缀
imageManagerInsertAlign {String} [默认值:"none"] //插入的图片浮动方式
imageManagerAllowFiles {Array}, //列出的文件类型
//默认值:
[".png", ".jpg", ".jpeg", ".gif", ".bmp"]
8. 列出指定目录下的文件
fileManagerActionName {String} [默认值:"listfile"] //执行文件管理的action名称
fileManagerListPath {String} [默认值:"/ueditor/php/upload/file/"] //指定要列出文件的目录
fileManagerUrlPrefix {String} [默认值:""] //文件访问路径前缀
fileManagerListSize {String} [默认值:20] //每次列出文件数量
fileManagerAllowFiles {Array} //列出的文件类型
//默认值:
[
".png", ".jpg", ".jpeg", ".gif", ".bmp",
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
6.1、上传接口跨域问题
ueditor/ueditor.all.js 8083行
注释 isJsonp = utils.isCrossDomainUrl(configUrl);
改为 isJsonp=false
6.2、上传图片鉴权问题
/ueditor/dialogs/image/image.js 707行
在header['X_Requested_With'] = 'XMLHttpRequest';下面添加
header['Authorization']=window.localStorage.getItem('token');
7.1、前端初始化UEditor时控制台报错:后台配置项返回格式出错,上传功能将不能正常使用
7.2、前端初始化报错:because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.
7.3、富文本编辑器Ueditor 报错: 请求后台配置项http错误,上传功能将不能正常使用
这里这种情况的出现是由于在客户端发出请求后,服务端由于一些原因迟迟未返回响应结果,导致客户端长时间未收到响应才出现这种报错。可能是因为后端断点或者其他情况。