什么是长连接短连接?
长连接经历TCP三次握手,webSorket请求;
短连接前端向服务器发送一次请求,服务器响应一次;
https://www.cnblogs.com/gotodsp/p/6366163.html
声明变量的关键字?区别?
var let const
var是全局的,let是局部的,const是常量
表单验证?输入框敏感词验证?
a 整个表单验证:
vue中,使用<el-form>包裹整个表单 在其中使用:model 绑定数据 和 :rules绑定校验规则,el-from-item包裹 传入prop (prop对应校验数据)
<el-form :model="form" refs="form" :rules="rules"></el-form>
<el-form-item prop="name"></el-form-item>
在script中添加使用数据 以及 校验规则
提交方法中:
this.$refs['form'].validate((valid) => {
//如果合法
if (valid) {}
})
b 敏感词验证:输入框绑定了失去焦点事件,然后再遍历敏感词数组进行匹配和替换
讲一下对uniapp的理解?
讲一个拿得出手的项目?
地图使用情况?实时监控定位?
https://blog.csdn.net/weixin_55846296/article/details/122977534
避免表单重复提交?
a. 禁掉提交按钮。表单提交后,通过 JavaScript 将提交按钮设置为 disable。
这种方法能够防止用户重复提交。但是如果客户端把 JavaScript 禁止,这种方法就无效了。
b. Post/Redirect/Get 模式,在提交后执行页面重定向,这就是所谓的 Post-Redirect-Get (PRG) 模式。当用户提交了表单后,执行一个客户端的重定向,转到提交成功信息页面。 这能避免用户按F5导致的重复提交,而其也不会出现浏览器表单重复提交的警告,也能消除按浏览器前进和后退按导致的同样问题。
c. 在数据库里添加约束。在数据库里添加唯一约束或创建唯一索引,防止出现重复数据。这是最有效的防止重复提交数据的方法。
d. 在 session 中存放一个特殊标志。当表单页面被请求时,生成一个特殊的字符标志串,存在 session 中,同时放在表单的隐藏域里。接受处理表单数据时,检查标识字串是否存在,并立即从 session 中删除它,然后正常处理数据。 如果发现表单提交里没有有效的标志串,这说明表单已经被提交过了,忽略这次提交。 这使你的 Web 应用有了更高级的 XSRF 保护。
小程序登录流程?
1.调用 wx.login() 获取 临时登录凭证 code,有效期为 5分钟;(临时登录凭证 code 只能使用一次)
2.将临时 code 传到我们的后端,后端调用 auth.code2Session 接口,换取用户唯一标识 OpenID 和 会话密钥 session_key;( openid 是用户唯一标识,session_key 能保证当前用户进行会话操作的有效性)
注意:获取 session_key 出于安全性的考虑,要在后端调用。如果我们在前端通过 request 调用此接口,就不可避免的需要将我们小程序的appid 、secret 和服务端下发的 session_key 暴露在外部,会给我们的业务安全带来极大的风险。
session_key 拥有一定的时效性。用户越久未使用小程序,用户登录态越有可能失效。反之如果用户一直在使用小程序,则用户登录态一直保持有效。具体时效逻辑由微信维护,对开发者透明。开发者需要调用 wx.checkSession 接口检测当前用户登录态是否有效。
3.后端自定义新的密钥并关联返回的 session_key 和 openid,将新的密钥返给前端,前端将其存储在 storage 中。(会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥,所以要定义新的密钥)。
之所以存在storage中,是因为小程序没有 cookie,相应的后端 set-cookie 在小程序中不起作用。
4.前端发送请求的时候,带着密钥,后端根据密钥识别用户身份,返回数据。
1.通过 wx.login() 获取到用户的code判断用户是否授权读取用户信息,调用wx.getUserInfo 读取用户数据。
2.由于小程序后台授权域名无法授权微信的域名,所以需要自身后端调用微信服务器获取用户信息。
3.通过 wx.request() 方法请求业务方服务器,后端把 appid , appsecret 和 code 一起发送到微信服务器。
appid 和 appsecret 都是微信提供的,可以在管理员后台找到。
4.微信服务器返回了 openid 及本次登录的会话密钥 session_key。
5.后端从数据库中查找 openid ,如果没有查到记录,说明该用户没有注册,如果有记录,则继续往下走。
6.session_key 是对用户数据进行加密签名的密钥。为了自身应用安全,session_key 不应该在网络上传输。
7.然后生成 session并返回给小程序。
8.小程序把 session 存到 storage 里面。
9.下次请求时,先从 storage 里面读取,然后带给服务端。
10.服务端对比 session 对应的记录,然后校验有效期。
web端扫码登录?
获取二维码url和code,进入轮询,接口返回token存储到本地,否则就绑定手机号登录。
// 获取二维码
getwechatCode() {
getQrcode().then((res) => {
if (res.code == 1) {
this.scan_value = res.data.code;
this.qr_url = res.data.qrcode_index_url;
this.checkLogin();
}
});
},
// 扫码轮训接口
checkLogin() {
var self = this;
self.timer = setInterval(() => {
self.time++;
if (self.time >= 20) {
clearInterval(self.timer);
self.timer = null;
self.time = 0;
self.getwechatCode();
}
// 轮训内容
checkLoginStatus({
code: this.scan_value,
}).then((res) => {
// 未登录状态,继续轮训
// console.log(res)
// return
if (res.code == 1) {
}
// 登录状态,清楚定时器并刷新页面
if (res.code == 2) {
clearInterval(self.timer);
self.timer = null;
self.time = 0;
console.log(res.data);
localStorage.setItem("token", res.data.token);
self.getUser();
}
//绑定手机号码
if (res.code == 3) {
clearInterval(self.timer);
self.timer = null;
self.bindData = res.data;
self.time = 0;
self.$store.commit("user/SET_SHOW", false);
self.bindMobileShow = true;
}
});
}, 3000);
},
promise理解?
一个组件如何引用另一个组件的方法?import和require的区别?
vue页面跳转传参?
vue组件传值?
https://blog.csdn.net/m0_62876802/article/details/125783872
web端扫码支付
创建订单->返回二维码、订单信息等->传订单号进入支付结果轮询
submit() {
this.createOrder()
},
// 创建订单
createOrder() {
var that = this
const data = {
child_num: this.memberCardInfo.num,
pay_type: this.payIndex == 1 ? 'alipay' : 'wechatpay',
vip_type: this.typeIndex
}
this.loading = true
applyVip(data).then(res => {
// this.loading = false
if (res.code == 1) {
this.code_url = res.data.code_url
this.order_no = res.data.order_no
this.fee = res.data.fee
// this.$store.commit('user/SET_MEMBERSHOW', false);
if (this.payIndex == 1) {
window.open(this.code_url, '_blank');
this.getResult()
} else {
this.payDialog = true
this.$nextTick(() => {
document.getElementById("qrcode").innerHTML = '' //先清空之前生成的二维码
if (this.code_url) {
this.transQrcode(this.code_url)
}
})
}
} else {
this.loading = false
this.$message.error(res.msg)
}
})
},
// 链接转二维码
transQrcode(url) {
let qrcode = new QRCode("qrcode", {
width: 140, // 二维码宽度,单位像素
height: 140, // 二维码高度,单位像素
text: url // 生成二维码的链接
});
this.getResult()
},
// 支付结果查询
getResult() {
var self = this
self.timer = setInterval(() => {
// 轮训内容
applyVipResult(self.order_no).then(res => {
// 支付成功
if (res.code == 1) {
// 待支付
if (res.data.info.status == 1) {
self.time++
// if (self.time >= 20) {
// clearInterval(self.timer)
// self.timer = null
// self.time = 0
// self.createOrder()
// }
}
// 支付成功
if (res.data.info.status == 2) {
clearInterval(self.timer)
self.timer = null
self.time = 0
self.payDialog = false
this.loading = false
self.$store.commit('user/SET_MEMBERSHOW', false);
self.$store.dispatch('user/GetRoleMenu')
self.$message.success('支付成功')
self.$emit('resetBtn')
self.getUser()
}
// 支付失败
if (res.data.info.status == 3) {
clearInterval(self.timer)
self.timer = null
self.time = 0
self.payDialog = false
this.loading = false
self.$message.error('支付失败')
}
}
})
}, 3000);
},