最近项目告一段落,总结一下值得记录的问题
1. 上传到阿里云的图片,返回的地址在pc端展示正常。小程序上无法展示
原因:图片名称中含有逗号,通过oss地址打开无法预览,逗号后面的后缀被切掉了
只找到这个提问
解决:目前是在上传的时候限制过滤名称中有逗号的。
2. 第三方平台获取到了授权公众号的二维码,在web上展示:此图片来自微信公众平台 未经允许不可引用
原因:别人设置了防盗链
解决
我这里只有一张公众号二维码展示,直接在img标签上用. (修改后一定要清空缓存才能看到效果)
方案1.添加meta标签
给页面添加一个meta标签,在meta标签里指定referrer的值
MDN的标准:
Whatwg的标准:
影响:标签name="referrer"属性主要用于控制网页发送给服务器的referrer信息,可以告诉服务器端用户是从哪个页面来到当前网页的,如果来源不是白名单域名就不展示
如果用 设为never后,也会造成一定的问题,比如在后台中使用了该标签,会导致js和php的一些跳转出现问题,比如js的history.back()方法将找不到上一个页面,因为被禁止referrer了,php的$_[‘HTTP_REFERRER’] 也同样为空值
同时该属性会导致一些第三方的统计代码失效,比如cnzz,百度统计,解决方法是使用iframe包裹一层,用一个单独的html加载统计代码
方案2.添加ReferrerPolicy属性
ReferrerPolicy (MDN:引用头将被完全省略,没有请求信息随请求一起发送。)
//
兼容:
referrerPolicy="no-referrer"
Chrome yes yes yes
Firefox yes yes yes
Edge/IE yes no no
看以下红圈不同的标签上用不同的属性
3.如下图:uniapp中聚焦键盘顶起uView的popup
小程序键盘高度顶起弹窗,不要在键盘变化事件里,加键盘高度赋值给弹窗高度。最好用样式直接用键盘高度改变bottom
因为在部分ios机型uni.onKeyboardHeightChange 或者@keyboardheightchange 高度会变化5次,高度一直加就顶到天了
// 活的键盘高度顶起来
handlefocus({ detail: { height } }) {
// const pxTorpx = height ? height / (uni.upx2px(height) / height) : 0
this.popupBottom = height
},
4. vue项目 在跳转路由后,上个页面的请求还在执行,如果失败,请求提示会出现在新页面,这样不好
解决: 跳转后取消上个页面的请求
在axios封装拿到那个请求的cancel方法存到store,
const CancelToken = axios.CancelToken
axios.interceptors.request.use(
config => {
config.cancelToken = new CancelToken((cancel) => {
store.commit('setting/pushRequest', {
cancelRequest: cancel
})
})
return config
},
error => {
return Promise.reject(error)
}
)
路由跳转进行清空
router.beforeEach((to, form, next) => {
store.commit('setting/clearRequest') // 取消请求
})
//state
cancelRequestArr: [], // 取消请求token数组
//mutation
pushRequest(state, payload) {
state.cancelRequestArr.push(payload.cancelRequest)
},
clearRequest({ cancelRequestArr }) {
cancelRequestArr.forEach(item => {
// 取消请求
item()
})
// 实践中发现直接等于[] ,并不能有效清空数组。等于0 更高效
// 求解释??
cancelRequestArr.length = 0
}
5. v-model.number 限制的是正整数,如果我要想正整数和小数都能输入呢,翻了翻找到这个比较好,记录一下。原文地址
下面限制两位小数
const number = {
bind(el, binding, vnode) {
// 扩展到element这种库
const input = el.tagName === 'INPUT' ? el : el.querySelector('input')
input.addEventListener('compositionstart', () => {
vnode.inputLocking = true
})
input.addEventListener('compositionend', () => {
vnode.inputLocking = false
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', () => {
if (vnode.inputLocking) {
return
}
const oldValue = input.value
let newValue = input.value
newValue = newValue.replace(/[^\d.]/g, '')
newValue = newValue.replace(/^\./g, '')
newValue = newValue.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
newValue = newValue.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
if (newValue) {
const arr = newValue.split('.')
newValue = Number(arr[0]) + (arr[1] === undefined ? '' : '.' + arr[1]) // 去掉开头多余的0
}
// 判断是否需要更新,避免进入死循环
if (newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
// input 事件无法处理小数点后面全是零的情况 因为无法确定用户输入的0是否真的应该清除,如3.02。放在blur中去处理
input.addEventListener('blur', () => {
const oldValue = input.value
let newValue = input.value
if (newValue) {
newValue = Number(newValue).toString()
}
// 判断是否需要更新,避免进入死循环
if (newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
}
}
export default (Vue) => {
Vue.directive('inputFloat', number)
}
6. vue项目在chrome浏览器出现警告
解决很简单,(直接扣下面插件代码也行,就丁点代码)
npm i default-passive-events -S
在main.js 引入 import 'default-passive-events'
为什么会有这个提示?
它是 高版本浏览器事件监听里的一个属性,默认false。部分浏览器已经将文档级节点document,windows的监听的这个属性值改为了true
addEventListener(type, listener, {
capture: false, //捕获
passive: false,
once: false //只触发一次
})
所有的现代浏览器,即使在很昂贵的js运行下,也会有一个线程式的滚动特性来允许流畅的滚动,但是,touchstart和touchmove调用preventDefault()能阻止滚动,所以这个滚动优化在有时候会被touchstart和touchmove的所限制。鼠标,触摸事件可以阻止滚动,滚动就会等待监听里面的代码执行,即使是空监听也会耗时
上面的插件就是给所有,自己写的,所有mouse,touch,scroll监听事件加上true
点我看MDN上更详细的
7. vue项目引入地图有警告提示
Parser was blocked due to document.write(
它之所以为用户提供 JS 代码,而不是 HTML 代码,是为了先用 JS 判断出该用 http 还是 https 协议
解决:从外部资源的加载看解决办法
- 浏览器加载外部资源,是并行下载达到预解析预加载的目的,执行和渲染还是线性的
如: 下面三个脚本,每个单独下载时间为1s,几秒后能看到img呢。
答案:只需要1s
- 如果 b是被document.write加载的,a,c并行,b要等到a下载完后才会下载,总体2s
')
从报错上看,可以直接将document.write中加载的真实资源,写在head里,这样浏览器就可以预加载了,也不会警告了,算是进行优化了,但这并不是最佳的优化。
- 这样做舍弃了 资源的动态参数(时间戳,更新最新资源)
- 外部资源一般比较大,放在头部影响页面的加载。建议最好异步
api 改为getscript
异步才是王道,官网有案例
document.createElement("script")
记录:上面仅仅是警告提示本身不影响运行,而我正视这个记录的原因是:某天反馈访问项目,地图加载报错导致了界面错误
虽然后来没有复现,应该和代码的加载顺序有关,已改为异步且不影响其他逻辑
关于chrome的优化和document.write不建议使用的更多介绍