1. 标点符号不规范,如使用引号统一使用双引号,去掉不必要空格,js句尾使用;
2. 定义变量时注意使用var、let、const;
3. 语句过长时换行;
4. 复杂的ajax请求:
$.ajax({
url: '/api/open/comment/getEntityComments',
data: JSON.stringify({
"entityId": id,
"commentEntityType": "video",
"pageIndex": 1,
"pageSize": 10
}),
method: 'POST',
dataType: 'json',
contentType: "application/json",
success: function (res) {}
})
5. git 版本回退
因为每次 COMMIT提交,都会保存“快照”版本,并记录到日志中,可以通过 GIT LOG 查看日志记录回退到某个版本
如果发现要回退的那个版本消失了,可以通过 GIT REFLOG 来找那个版本,这个指令记录了执行的每一条指令
$ git reset --hard HEAD^ #回退到上一个版本
$ git reset --hard HEAD^^ #回退到上上个版本
$ git reset --hard HEAD~10 #回退到之前10个版本
$ git reset --hard 5185793 #回退到版本号开头是5185793的版本
6. git 问题You have not concluded your merge (MERGE_HEAD exists).Please, commit your changes before you can merge.
解决方法:
是之前的拉动无法自动合并并进入冲突状态。在下次拉动之前,冲突没有得到妥善解决。
1. 撤消合并并再次拉动。
撤消合并:
git merge --abort [自git 1.7.4版]
git reset --merge [先前的git版本]
2. 解决冲突。
3. 不要忘记添加并提交合并。
4. git pull 现在应该工作正常。
7.HTTP2.0自定义头部设置的大写会全部变成小写
在做小程序项目上,自定义了一个header属性值Set-Token,在第一次请求的时候带着这个请求头信息,以后请求就不用带了。在JS进行判断头部信息的时候,没有忽略大小写进行判断。因为之前一直使用http1.1协议,所有一直没问题。
后来运维改用http2.0协议,线上用户反馈出了问题,ios系统的手机加载不出页面。经过排查,正是JS判断头部信息的地方出了问题,明明设置的是首字母大写,结果变成了全小写,导致后面的请求没有发出。而在安卓机上并没有这个问题。
后来的解决方法是把请求头信息都改为小写,继续使用http2.0
8. ios兼容问题
ios不支持ES6写法,比如let、const,箭头函数。
小程序web-view,在ios不显示,显示空白页面,解决方法是将url进行encodeURI
9. 小程序在华为手机上不显示网页信息
最简单方法就是重启
10. js对比数组相等
简单的方法,数组排序后转为字符串:var arr = new Array; arr.sort().toString();
11.小程序返回按钮
页面跳转的时候调用wx.redirectTo会先关闭父页面再跳转,wx.navigator不会关闭父页面
12. 通过$.ajax()加载网页信息拼接在iframe中
加载网页信息后拼接在iframe的body中,为了网页里加载的css不影响iframe外的页面样式,在iframe页面里设置base标签。
$.ajax({
url: url,
type: 'get',
dataType: 'html',
async: false,
success: function (data) {
console.log("compile")
//添加基础路径
data = data.replace('<head>', '<head><base href="' + epath + '" />')
$("#" + iframeId).contents().find("body").html(data);
}
})
13.解决touch和click事件冲突问题
页面上同时存在touch和click事件,在touch事件中进行判断滑动的距离,如果没有滑动距离,执行click事件
14.js添加随机数重新加载
<script type="text/javascript">
document.write("<script type='text/javascript' src='js/cours_details.js?random=" + Math.random() + "'></s" + "cript>");
</script>
15.分享网页到微信
重新加载的方法:
window._bd_share_main.init();
16.schema_reference.4: 无法读取方案文档 ‘http://cxf.apache.org/schema/jaxws.xsd’, 原因为 1) 无法找到文档; 2) 无法读取文档; 3)
将地址重新剪切复制,保存。
参考:Spring如何加载XSD文件(org.xml.sax.SAXParseException: Failed to read schema document错误的解决方法)_bluishglc的博客-CSDN博客
17.window.location.href 参数是中文乱码
传参时对参数进行编码: encodeURI(encodeURI(inquireName))
接收参数的时候解码:decodeURI(inquireName)
18.nginx操作命令
ps -ef | grep nginx 查询nginx主进程号
/usr/nginx/sbin/nginx -t 检查配置,同时也是输出配置文件所在位置
/usr/local/nginx/nginx -s {参数}
stop - 快速关机
quit - 优雅的关机
reload - 重新加载配置文件
reopen - 重新打开日志文件
19.+、*、|、\、?、^ 等符号在正则表达示中有不同意义,只需要加[]、或是\即可!
20.vue.js在href中传参
:href="'/m/signcode/scan?id='+item.id+''"
21. js截取字符串后四位
"abcdefg".slice(-4)
22. js 数组转字符串
[1,2,3].join(",")
22. vue加载完页面前出现undefined
在要显示字段的地方加v-if判断,当有值的时候再渲染页面
23. 页面文字过长隐藏,显示…
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 110px;
24.解决arthas中文乱码问题
java -jar -Dfile.encoding=gbk arthas-client.jar
25. 在项目中使用aop记录日志问题
在项目中使用aop记录日志问题,方法名称为createLog,导致在一个查询接口中获取并修改了实体类(但不保存该实体),执行了更新实体类的方法,经排查是事务造成的对实体类执行update操作,解决方法是修改了createLog方法名,在该方法上不执行事务。
26.chrome 升级79版本后非同源域名不传递cookie,可以设置多个cookie值,后台获取的时候判断
package com.whaty.cbs.plugins.web.frame;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
public class CookieFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 获取响应回去的所有cookie, 如果是Secure添加SameStie=None属性
Collection<String> cookieFromResponse = getCookieFromResponse((HttpServletResponse) response);
// 复制一批带有Secure属性的cookie, 再添加到response中
for (String cookie : cookieFromResponse) {
((HttpServletResponse)response).addHeader("Set-Cookie", cookie);
}
// 放行
chain.doFilter(request, response);
}
private static Collection<String> getCookieFromResponse(HttpServletResponse response) {
// 拿到所有cookie
Collection<String> headers = response.getHeaders("Set-Cookie");
Collection<String> strings = new ArrayList<>(headers.size());
for (String header : headers) {
// 如果cookie是Secure, 添加 SameSite=None
if (header.contains("Secure")) {
// 如果是https, 添加同站属性
header += "; SameSite=None;";
}
strings.add(header);
}
return strings;
}
@Override
public void destroy() {
}
}
<!--chrome80浏览器支持cookie-->
<filter>
<filter-name>cookieFilter</filter-name>
<filter-class>com.whaty.cbs.plugins.web.frame.CookieFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cookieFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
27、视频分片上传
public String chunkupload(){
HttpServletRequest request = ServletActionContext.getRequest();
MultiPartRequestWrapper mrequest = (MultiPartRequestWrapper) request;
File[] files = mrequest.getFiles("Filedata");
if(files.length > 0){
File file = files[0];
String guid = mrequest.getParameter("id");
int chunk = Integer.parseInt(mrequest.getParameter("chunk"));
int chunks = Integer.parseInt(mrequest.getParameter("chunks"));
String size = mrequest.getParameter("size");
String savePath = "/incoming/file/chunk/"+guid;
try {
String realPath = FileUtils.getFileSaveRealPath(savePath);
File tmp = new File(realPath+"/" + chunk);
org.apache.commons.io.FileUtils.copyFile(file, tmp);
System.out.print("chunk:"+chunk +" chunks: "+chunks);
if(chunk==(chunks-1)){
String saveFilePath = mergeFile(mrequest);
String result = uploadVideo(saveFilePath);
return result;
}
this.setJsonString("true");
} catch (Exception e) {
e.printStackTrace();
this.setJsonString("false");
}
}else{
this.setJsonString("false");
}
return "json";
}
public String mergeFile(MultiPartRequestWrapper mrequest) throws Exception {
String fileName = mrequest.getParameter("name");
String chunks = mrequest.getParameter("chunks");
String guid = mrequest.getParameter("id");
String path = "/incoming/file/video/" + guid;;
String chunkPath = FileUtils.getFileSaveRealPath("/incoming/file/chunk/" + guid);
// 创建 合并后的文件
String savePath = path +"/"+ fileName;
String realPath = FileUtils.getFileSaveRealPath(path);
File newFile = new File(realPath+"/"+fileName);
if (!newFile.exists()) {
newFile.createNewFile();
}
FileOutputStream outputStream = new FileOutputStream(newFile, true);// 文件追加写入
byte[] byt = new byte[10 * 1024 * 1024];
int len;
FileInputStream temp = null;// 分片文件
for (int i = 0; i < Integer.parseInt(chunks); i++) {
temp = new FileInputStream(new File(chunkPath+ "/" + i));
while ((len = temp.read(byt)) != -1) {
outputStream.write(byt, 0, len);
}
temp.close();
}
// 当所有追加写入都写完 才可以关闭流
outputStream.close();
// 删除分片文件
org.apache.commons.io.FileUtils.deleteDirectory(new File(chunkPath));// 删除目录下所有的内容
return savePath;
}
public String uploadVideo(String filePath) {
try {
ScormCourseItem item =null;
try {
HttpServletRequest request = ServletActionContext.getRequest();
MultiPartRequestWrapper mrequest = (MultiPartRequestWrapper) request;
String fileNames = mrequest.getParameter("name");
videoPath = filePath;
boolean flagAliYun = Boolean.parseBoolean(Const.getMapValue("videoAliYun"));
String videoImgPath = "";
String origin = "";
File filevideo = new File(FileUtils.getFileSaveRealPath(videoPath));
MultimediaInfo video = createVideoJpg(filevideo, videoPath);
if(flagAliYun){ //阿里云上传
origin = PlatformConstant.ORIGIN_ALIYUN;
}else{
origin = PlatformConstant.ORIGIN_LOCAL;
}
String videoJpg = video.getImagePath();
String jpgPath = "";
if(StringUtils.isNotBlank(videoJpg)){
videoJpg = videoJpg.substring(videoJpg.lastIndexOf(File.separator)+1); //此处只截取图片路径中的图片文件名称
jpgPath = this.getVideoPath().substring(1, this.getVideoPath().lastIndexOf("/")+1);
}
//阿里云上传 //TODO
videoImgPath = jpgPath + videoJpg;
ScormCourseItem parentItem = getCourseItemById(groupId);
String resourceName = fileNames;
resourceName = resourceName.substring(0, resourceName.lastIndexOf("."));//不带后缀名
item = saveCourseItem(parentItem, resourceName, columnId);
CourseSpaceResources cr = new CourseSpaceResources();
cr.setName(fileNames);
cr.setScormCourseItem(item);
cr.setType(ColumnTypeUtil.VIDEO.getValue());
cr.setCreateDate(new Date());
cr.setVideoTime(video.getDurationStr());
cr.setResource(videoPath);
cr.setVideoJpg(videoImgPath); // jpgPath + videoJpg
cr.setOrigin(origin); // PlatformConstant.ORIGIN_LOCAL
cr.setPeTchCourse(item.getScormCourseInfo().getPeTchCourse());
Object object = this.getGeneralService().save(cr);
if(object instanceof CourseSpaceResources && object != null){
String realPath = FileUtils.getFileSaveRealPath(videoPath);
ALiVideoAttributeTask task = new ALiVideoAttributeTask(fileNames,((CourseSpaceResources) object).getId(), realPath, flagAliYun);
MultiDataSourceThread mdst = new MultiDataSourceThread(task);
mdst.threadHandle();
}
addCourseScoreGroup(item);//设置考核
//设置要返回的数据
itemBean = parentItem;
List<CourseSpaceResources> resources = new ArrayList<CourseSpaceResources>();
resources.add(cr);
item.setResourceList(resources);
courseItemList = new ArrayList<ScormCourseItem>();
courseItemList.add(item);
return "showRes";
} catch (Exception e) {
e.printStackTrace();
if(item != null) {
this.getGeneralService().delete(item);
}
try {
String file = FileUtils.getFileSaveRealPath(this.getVideoPath());
FileUtils.rmFile(file, false);
} catch (Exception e1) {
e1.printStackTrace();
}
}
} catch (EntityException e1) {
e1.printStackTrace();
}
this.setJsonString("false");
return "json";
}
/**
* 根据视频生成图片
* @param video 视频文件
* @param videoPath 视频地址
* @return
* @throws Exception
*/
private MultimediaInfo createVideoJpg(File video, String videoPath) throws Exception{
Map<String, Object> result = new HashMap<String, Object>();
Encoder encoder=new Encoder();
String v = FileUtils.getFileSaveRealPath(videoPath);
v = v.substring(0, v.lastIndexOf(".")) + ".jpg";
MultimediaInfo info = encoder.getInfo(video, new File(v));
return info;
}
<script type="text/javascript">
$(function() {
var columnId = $("#pointArea_<s:property value='groupId' />").find("input[name='column_id']").val();
var _this = $('#addVideo_<s:property value="groupId" escape="false"/>')[0];
var _proTool = 'proTool_<s:property value="groupId" escape="false"/>';
var _uploadTool = 'uploadTool_<s:property value="groupId" escape="false"/>';
var hiddenVideoUploadToolId = 'hiddenVideoUpload_<s:property value="groupId" escape="false"/>';
//var uploaderUrl = CommonUtil.getPlatformPath()+'/course/design/courseTeachingUploadVideo_uploadVideo.action';
var uploaderUrl = CommonUtil.getPlatformPath()+'/course/design/courseTeachingUploadVideo_chunkupload.action';
uploaderUrl = CommonUtil.getUploadUrl(uploaderUrl);
var $selectFile = $("#addVideo_<s:property value="groupId" escape="false"/>");
var lastPercentage = 0;
var uploader = WebUploader.create({
auto: true,// 选完文件后,是否自动上传。
swf: CommonUtil.getPlatformPath() +'/resource/common/js/plugins/webuploader/Uploader.swf',// swf文件路径
server: uploaderUrl,// 文件接收服务端。
fileVal:'Filedata',//{Object} [可选] [默认值:'file'] 设置文件上传域的name。
formData :{"groupId":"<s:property value='groupId' escape='false'/>", "columnId": columnId},//文件上传请求的参数表
pick: $selectFile, // 选择文件的按钮。可选。// 内部根据当前运行是创建,可能是input元素,也可能是flash.
fileNumLimit:1,
chunked:true,
chunkSize:512*1024,
fileSizeLimit:1000 * 1024 * 1024,
timeout: 0,
accept: {
title: 'intoTypes',
extensions: 'mp4,flv',
mimeTypes: 'video/mp4,video/x-flv'// fileType : ['video/mp4','video/x-flv'],
},
method:'POST',//{Object} [可选] [默认值:'POST'] 文件上传方式,POST或者GET。
});
$selectFile.find("div[class='webuploader-pick']").css({
"width":"135px",
"height":"40px",
"padding":"0px",
"line-height":"40px",
"font-weight":"bold",
"font-size":"14px"});//重置按钮样式
uploader.on( 'fileQueued', function( file) {
var $proTool=$('#'+_proTool);
$proTool.find(".cancel a").off("click");
$proTool.find(".cancel a").click(function(){
uploader.reset();
$('#'+hiddenVideoUploadToolId).hide();
$proTool.hide();
$('#' + _uploadTool).css("height","100%");
});
$('#'+hiddenVideoUploadToolId).show();
$proTool.show();
$('#' + _uploadTool).css("height","0px");
});
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
$('#' + _uploadTool).hide();
$('#' + _proTool).show();
$("#pointArea_<s:property value='groupId' /> .proGreen").css("width",percentage *100+"%");
var fileName = file.name;
if(fileName.length>30){
fileName = fileName.substring(0,29)+"...";
}
//计算剩余时间(文件剩余大小,除以当前速度)
var remainSize = (1 - percentage) * file.size;
var currentSpeed = (percentage - lastPercentage)* file.size;
if(currentSpeed == 0){
currentSpeed = file.size;//防止剩余时间提示无穷大
}
var lastTime = remainSize / currentSpeed;
var formatLastTime = CommonUtil.secondsToTimeStr(lastTime);
$("#pointArea_<s:property value='groupId' /> .proGreen span").html(fileName +" " + percentage *100+"%" +" " +formatLastTime);
lastPercentage = percentage;
});
uploader.on( 'uploadSuccess', function( file,data ) {
var obj = data;
console.log(data);
for(var i in obj){//用javascript的for/in循环遍历对象的属性
if($.trim(obj[i])=="false"){
alert("创建节点失败");
}else{
$('#pointArea_<s:property value="groupId" />').siblings(".goonAdd").show();
$('#pointArea_<s:property value="groupId" />').replaceWith(obj[i]);
}
}
});
uploader.on('error', function (code) {
var err = '';
switch (code) {
case 'Q_EXCEED_NUM_LIMIT':
err += '已达到队列最大数量,请选择更少的文件';
break;
case 'Q_TYPE_DENIED':
err += '不支持的文件类型';
break;
case 'Q_EXCEED_SIZE_LIMIT':
err += '文件大小超过限制';
break;
default:
err += '上传错误,请刷新重试!';
break;
}
alert(err);
});
});
</script>
28、pom.xml出现web.xml is missing and is set to true解决方案
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
29、mybatis错误处理
JRebel-SDK-CBP: ERROR Class ‘org.apache.ibatis.reflection.Reflector’ could not be processed by org.zeroturnaround.jrebel.mybatis.cbp.ReflectorCBP@org.apache.catalina.loader.WebappClassLoader@60f017: org.zeroturnaround.bundled.javassist.NotFoundException: forClass(..) is not found in org.apache.ibatis.reflection.Reflector
mybatis要用3.2.7, 3.3.0版本中Reflector类缺少forClass方法
WARN CacheConfiguration - Cache ‘Cache1’ is set to eternal but also has TTI/TTL set. To avoid this warning, clean up the config removing conflicting values of eternal, TTI and TTL. Effective configuration for Cache ‘Cache1’ will be eternal=’true’, timeToIdleSeconds=’0’, timeToLiveSeconds=’0’.
可以不管,或者修改ehcache.xml中配置
30、sql语句错误(ssoUser.phone
不加引号出错)
select u.* , s.phone as `ssoUser.phone`
from `user` u, priority_role p, sso_user s
where u.fk_priority_role_id = p.id
and u.fk_sso_user_id = s.id
and p.`code` = '4' and u.name like '%%'
31、扫描多个路径,存在两个名称相同的类,扫描时过滤掉
<context:component-scan base-package="com.windf">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<context:component-scan base-package="com.whaty">
<context:exclude-filter type="assignable" expression="com.whaty.framework.common.spring.SpringUtil" />
</context:component-scan>
32、浏览器缓存问题
可以在请求的JS后面加随机数
ajax请求cache:false,
1、在服务端加 header(“Cache-Control: no-cache, must-revalidate”);
2、在ajax发送请求前加上 anyAjaxObj.setRequestHeader(“If-Modified-Since”,”0″);
3、在ajax发送请求前加上 anyAjaxObj.setRequestHeader(“Cache-Control”,”no-cache”);
4、在 Ajax 的 URL 参数后加上 “?fresh=” + Math.random(); //当然这里参数 fresh 可以任意取了
5、第四种方法和第三种类似,在 URL 参数后加上 “?timestamp=” + new Date().getTime();
6、用POST替代GET:不推荐
33. springboot2.X引入actuator依赖无法查看endpoint
management:
endpoints:
web:
base-path: /actuator
exposure:
include: "*"
34. elasticsearch查询时termQuery查询中文匹配失败:
问题: elasticsearch查询时termQuery查询中文匹配失败:
searchSourceBuilder.query(QueryBuilders.termQuery(“title”, “乒乓球”));
解决方法:
将上述代码改为:
searchSourceBuilder.query(QueryBuilders.termQuery(“title.keyword”, “乒乓球”));
即可
"query": {
"term": {
"title": {
"value": "乒乓球",
"boost": 1
}
}
},
改为:
"query": {
"term": {
"title.keyword": {
"value": "乒乓球",
"boost": 1
}
}
},
35. es设置高亮不显示
es版本使用的是7.6.2,原因是matchQueryBuilder.fuzziness(Fuzziness.AUTO);去掉之后就可以了
36.Illegal mix of collations (utf8mb4_unicode_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation ‘=’
修改等号两边字段的编码
37.vue项目线上页面刷新报404
解决方法,修改nginx配置
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html; // 解决404问题
}
38.修改数据库存储的url
update site set url =concat('http://',url) where locate('http://',url)=0
39.枚举类比较的时候使用equals和是一样的,因为Enum重写了equals,内部使用判断
40. 使用foreach进行遍历的时候,跳过此次循环使用return;
41.element饿了么下拉框el-select选值后,框里不变的问题
问题:el-select 绑定的值发生了变化,但是对于显示的值没有变,
解决方法: 增加属性 @change=“$forceUpdate()”
42.在Spirng或Springboot中获取HttpServletRequest
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
43. mybatis 编写sql语句转换 运算符
<= : <![CDATA[ <= ]]>
= : <![CDATA[ >= ]]>
44. el-redio 不回显数据
先看label前有没有加冒号 : “:”的意思就是绑定一个动态变量,其次radio label为number类型可以直接回显
45. js 日期格式转换
function dateFormat(fmt, date) {
let ret;
const opt = {
"Y+": date.getFullYear().toString(), // 年
"m+": (date.getMonth() + 1).toString(), // 月
"d+": date.getDate().toString(), // 日
"H+": date.getHours().toString(), // 时
"M+": date.getMinutes().toString(), // 分
"S+": date.getSeconds().toString() // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
};
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) {
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
};
};
return fmt;
}
let date = new Date()
dateFormat("YYYY-mm-dd HH:MM:SS", date)
46. vue 页面中输入框不能修改,可能是因为在data中没有进行双向绑定
47. element ui table 对不齐
.el-table th.gutter {
display: table-cell !important
}
48.修改MySQL group_concat默认长度
默认长度是1024,修改方法
SELECT @@global.group_concat_max_len;
SHOW VARIABLES LIKE "group_concat_max_len"; #查询最大值
SET GLOBAL group_concat_max_len=1024000;
SET SESSION group_concat_max_len=1024000;
49.整形和字符串进行比较需要转换类型
Integer i = 1;
System.out.println("1".equals(i.toString()));
50.MySQL中字段类型是int类型时,进行相等判断时,如果比较值包含字母,首个字母后的字符无效。
51.格式化double类型数据,不使用科学计数法展示
public static String formatNum(Double num) {
//新建数字格式对象
NumberFormat nf = NumberFormat.getInstance();
//保留小数位2位
nf.setMaximumFractionDigits(2);
//是否保留千分位
nf.setGroupingUsed(false);
return nf.format(num);
}
52.js判空
function isNull(value) {
if (!value && typeof value != "undefined" && value != 0) {
return true;
} else {
return false;
}
}
53.localStorage 存取Boolean类型返回字符串,需要再次判断==‘true’