Amy's Blog

notes


  • Home

  • Tags

  • Categories

  • Archives

  • Sitemap

  • Search

如何配置虚拟机的ssh,跳板机配置ssh 文件可以简化输入

Posted on 2020-06-26 | In 开发机、虚拟机 , ssh | 0 comments | Visitors:

快速配置开发机(虚拟机)登录操作
vim 修改当前文件夹下的config文件

1
2
3
vim .ssh/config 
或
vim ~/.ssh/config

查看.ssh目录

1
2
3
cd /root/.ssh
或者
cd ~/.ssh

然后将ssh放进去,就可以不用每次输入用户名密码了
.ssh/config文件如下配置

1
2
3
4
5
##测试环境跳板机##
Host test
HostName 10.1.xxx.xxx
User 用户名
Port 22

保存后打开terminal 执行ssh test则登陆test的跳板机(虚拟机)上面了

如果没权限,输入

1
sudo su

当然还有更加高效的工具就是secureCRT 可以记录密码等可视化便捷操作
windows 安装操作secureCRT
mac 安装操作secureCRT 待补充,还可以做一些配色操作让界面看起来非常舒适

H5唤起App

Posted on 2020-06-26 | In Frontend前端 , H5WakeUpAPP | 0 comments | Visitors:

最近总接到落地页的需求,落地页的职责主要是引流,有以下几种类型
1、引导已经下载App的用户打开App
2、引导未下载App的用户下载App
3、引导未注册的用户注册
4、引导已经注册的用户进入我们的主页或者其他的操作
从数据上可以体现在用户停留在App的时间多了,或者增加了用户量

唤起App主要的媒介是什么呢?

URL Scheme

URL Scheme的组成

1
[scheme:][//authority][path][?query][#fragment]
App 微信 支付宝 淘宝 微博
URL Scheme weixin:// alipay:// taobao:// sinaweibo://
1
2
3
4
5
     行为(应用的某个功能)    
|
scheme://[path][?query]
| |
应用标识 功能需要的参数

URL Scheme 在 ios 9+ 上诸如 safari、UC、QQ浏览器中, iframe 均无法成功唤起 APP,只能通过 window.location 才能成功唤端。

Intent

安卓的原生谷歌浏览器自从 chrome25 版本开始对于唤端功能做了一些变化,URL Scheme 无法再启动Android应用。 例如,通过 iframe 指向 weixin://,即使用户安装了微信也无法打开。所以,APP需要实现谷歌官方提供的 intent: 语法,或者实现让用户通过自定义手势来打开APP。
安卓版本 4.4.4 以上机型的安卓自带浏览器、chrome 浏览器,需要通过 intent 跳转
intents文档

  • Intent 语法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    intent:
    HOST/URI-path // Optional host
    #Intent;
    package=[string];
    action=[string];
    category=[string];
    component=[string];
    scheme=[string];
    end;
    如果用户未安装 APP,则会跳转到系统默认商店。当然,如果你想要指定一个唤起失败的跳转地址,添加下面的字符串在 end; 前就可以了:
    1
    S.browser_fallback_url=[encoded_full_url]
  • 示例
    下面是打开 Zxing 二维码扫描 APP 的 intent。
    1
    2
    3
    4
    5
    6
    intent:
    //scan/
    #Intent;
    package=com.google.zxing.client.android;
    scheme=zxing;
    end;
    1
    <a href="intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;S.browser_fallback_url=http%3A%2F%2Fzxing.org;end"> Take a QR code </a>

    Universal Link

    为什么要使用 Universal Link

传统的 Scheme 链接有以下几个痛点:

  • 在 ios 上会有确认弹窗提示用户是否打开,对于用户来说唤端,多出了一步操作。若用户未安装 APP ,也会有一个提示窗,告知我们 “打不开该网页,因为网址无效”
  • 传统 Scheme 跳转无法得知唤端是否成功,Universal Link 唤端失败可以直接打开此链接对应的页面
  • Scheme 在微信、微博、QQ浏览器、手百中都已经被禁止使用,使用 Universal Link 可以避开它们的屏蔽( 截止到 18年8月21日,微信和QQ浏览器已经禁止了 Universal Link,其他主流APP未发现有禁止 )

如何让 APP 支持 Universal Link

有大量的文章会详细的告诉我们如何配置,你也可以去看官方文档,我这里简单的写一个12345。

  1. 拥有一个支持 https 的域名
  2. 在 开发者中心 ,Identifiers 下 AppIDs 找到自己的 App ID,编辑打开 Associated Domains 服务。
  3. 打开工程配置中的 Associated Domains ,在其中的 Domains 中填入你想支持的域名,必须以 applinks: 为前缀
  4. 配置 apple-app-site-association 文件,文件名必须为 apple-app-site-association ,不带任何后缀
  5. 上传该文件到你的 HTTPS 服务器的 根目录 或者 .well-known 目录下

Universal Link 配置中的坑

这里放一下我们在配置过程中遇到的坑,当然首先你在配置过程中必须得严格按照上面的要求去做,尤其是加粗的地方。

  • 域名问题

Universal Link 支持的域名最多只能支持到二级域名,如果你用到了三级域名,Universal Link 唤端是不会生效的。

  • 跨域问题

IOS 9.2 以后,必须要触发跨域才能支持 Universal Link 唤端。

IOS 那边有这样一个判断,如果你要打开的 Universal Link 和 当前页面是同一域名,ios 尊重用户最可能的意图,直接打开链接所对应的页面。如果不在同一域名下,则在你的 APP 中打开链接,也就是执行具体的唤端操作。

  • Universal Link 是空页面

Universal Link 本质上是个空页面,如果未安装 APP,Universal Link 被当做普通的页面链接,自然会跳到 404 页面,所以我们需要将它绑定到我们的中转页或者下载页。

唤端方式

  • Android中,不同浏览器对唤起APP有严重的兼容性问题,主要处理方案有以下几种:
    1、window.location.href
    2、通过创建 iframe 并为其 src 赋值(主要)
    3、通过 intent
    4、通过制造不可见 a 链接,并触发点击

  • ios中,不同浏览器对唤起APP有严重的兼容性问题,主要处理方案有以下几种:
    1、系统版本在 8 以下时,可以监听页面的 pagehide / visibilitychange 事件。
    2、 window.location.href (主要)
    系统版本大于 8 以后可以 URL scheme 进行跳转。 IOS9 可以使用 universal Link

这里我们结合了两种来处理。

判断唤端是否成功

在浏览器实际上是没有能力判断手机里是否安装了某个App的,所以只能够采取一种投机取巧的方式。APP 如果被唤起的话,页面就会进入后台运行。setInterval 在 ios 中不会停止运行,在 android 中停止运行。

  • ios 通过 document.hidden 和 document.webkitHidden 属性来判断 APP 在 ios 中是否被正常唤起,2000ms 内,页面转入后台运行,document.hidden 会返回 true,代表唤端成功,反之则代表失败。
  • Android 我们的判断条件比预期时间多设置了 500ms,所以如果安卓中 setInterval 内的函数执行 100 次以内所费时间超过 2500ms,则说明 APP 唤起成功,反之则代表失败。
    在JavaScript中判断页面是否进入后台来判断打开成功。Html5提供了下列事件和属性可以利用:
    pagehide : 页面隐藏时触发
    visibilitychange : 页面隐藏没有在当前显示时触发(切换tab也会触发该事件)
    document.hidden : 当页面隐藏时,该值为true,显示时为false
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    const initialTime = new Date();
    let counter = 0;
    let waitTime = 0;
    const checkOpen = setInterval(() => {
    count++;
    waitTime = new Date() - initialTime;
    if (waitTime > 2500) {
    clearInterval(checkOpen);
    cb();
    }
    if (counter < 100) return;
    const hide = document.hidden || document.webkitHidden;
    if (!hide) {
    cb(); // 唤端失败的回调函数
    }
    }, 20);

如果唤端失败(APP 未安装),我们总是要做一些处理的,可以是跳转下载页,可以是 ios 下跳转 App Store… 但是Js 并不能提供给我们获取 APP 唤起状态的能力,Android Intent 以及 Universal Link 倒是不用担心,它们俩的自身机制允许它们唤端失败后直接导航至相应的页面,但是 URL Scheme 并不具备这样的能力,所以我们只能通过一些很 hack 的方式来实现 APP 唤起检测功能。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const browser = {
getBrowser: function() {
var u = navigator.userAgent,
app = navigator.appVersion;
return {
trident: u.indexOf('Trident') > -1, //IE内核
presto: u.indexOf('Presto') > -1, //opera内核
webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
opera: u.indexOf('Opera') > -1,
chrome: u.indexOf('Chrome') > -1,
firefox: u.indexOf('Firefox') > -1,
safari: u.indexOf('Safari') > -1, //注意chrome浏览器此项也为true,非chrome且此项为true则可确定为Safari
ie: u.indexOf('compatible') > -1 && u.indexOf('MSIE') > -1 && u.indexOf('Gecko') == -1,
mobile: u.search(/AppleWebKit.*Mobile/) > -1, //是否为移动终端
ios: u.search(/\(i[^;]+;( U;)? CPU.+Mac OS X/) > -1, //ios终端
android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android终端
winPhone: u.search(/Windows Phone/) > -1, //windows phone终端
iPhone: u.indexOf('iPhone') > -1, //是否为iPhon
iPad: u.indexOf('iPad') > -1, //是否iPad
webApp: u.indexOf('Safari') == -1, //是否Safari web应该程序,没有头部与底部
weibo: u.search(/WeiBo/i) > -1, //是否微博
weixin: u.search(/MicroMessenger/i) > -1, //是否微信
qq: u.search(/\sQQ/i) > -1, //是否QQ
mQQ: u.search(/MQQBrowser/) > -1, //是否QQ手机浏览器
uc: u.search(/UCBrowser/) > -1 //是否UC浏览器
};
}(),
getIOSVersion: function getIOSVersion() {
const verion = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/);
return parseInt(verion[1], 10);
}()
}
/**
* [evokeApp 唤起APP]
* @param {[Object]} config [跳转的URL]
* config.ios.url {[String]} [iOS跳转的URL]
* config.ios.data {[String]} [iOS URL参数]
* config.ios.callback {[function]} //android的回掉如果没有下载app就执行操作
* config.android.url {[String]} [android跳转的URL]
* config.android.data {[String]} [android URL参数]
* config.android.callback {[function]} //android的回掉如果没有下载app就执行操作
*/
const evokeApp = (config) =>{
//对微信,微博,qq做处理弹窗
if (browser.versions.weibo || browser.versions.weixin || browser.versions.qq) {
return;
}
//
let browserVersions = browser.versions;
let evokeAppURL = '';
let cb;
if (browserVersions.ios) {
evokeAppURL = config.ios.data ? 'authority://' + config.ios.url + '?' + config.ios.dataArr.join('&') : 'authority://' + config.ios.url;
cb = config.ios.callback;
} else if (browserVersions.android) {
evokeAppURL = config.android.data ? 'authority://' + config.android.url + '?' + config.android.dataArr.join('&') : 'authority://' + config.android.url;
cb = config.android.callback;
};
const initialTime = new Date();
let counter = 0;
let waitTime = 0;
const checkOpen = setInterval(() => {
count++;
waitTime = new Date() - initialTime;
if (waitTime > 2500) {
clearInterval(checkOpen);
cb && cb();
}
if (counter < 100) return;
const hide = document.hidden || document.webkitHidden;
if (!hide) {
cb && cb(); // 唤端失败的回调函数
}
}, 20);
}

注意

1、h5在微信中无法唤醒App,需要“用浏览器打开”
微信对所有的分享连接做了scheme屏蔽,也就是说分享连接中所有对于scheme的调用都被微信封掉了。

  1. 在询问是否打开APP的时候,如果选择了“取消”,则再唤起APP的时候会不起作用。目前并没有什么解决方案,在chrome Android,UC Android上会复现问题。需再次刷新页面才行。

  2. 在ios手机中,用location.href唤起app,本地如果没装app,会弹窗提示safari浏览器打不开该网页,网址无效,后面在用location.href来下载安装包的话也会显示同样的错误,即使你的下载链接是有效的。解决办法:IOS9及以上使用 Universal Links。

感谢作者
参考博客
实现文章

问题跨域

前端开发经常面临跨域问题,恩Universal Link也有跨域问题,但不一样的是,Universal Link,必须要求跨域,如果不跨域,就不行,就失效,就不工作。(iOS 9.2之后的改动,苹果就这么规定这么设计的)

这也是上面拿知乎举例子的时候重点强调的一个问题,知乎为什么使用oia.zhihu.com做Universal Link?

  • 假如当前网页的域名是 A
  • 当前网页发起跳转的域名是 B
  • 必须要求 B 和 A 是不同域名,才会触发Universal Link
  • 如果B 和 A 是相同域名,只会继续在当前WebView里面进行跳转,哪怕你的Universal Link一切正常,根本不会打开App

是不是不太好理解,那直接拿知乎举例子

https://www.zhihu.com/question/22914651

知乎的一般网页URL都是www.zhihu.com域名,你在微信朋友圈看到了知乎的问题分享,如果copy url 你就能看到这样的链接
微信里其实是屏蔽Schema的,但是你依然能看到大大的一个按钮App内打开,这确实就是通过Universal Link来实现的,但如果知乎把Universal Link 配在了www.zhihu.com域名,那么即便已经安装了App,Universal Link也是不会生效的。

一般的公司都会有自己的主域名,比如知乎的www.zhihu.com,在各处分享传播的时候,也都是直接分享基于主域名的url,但为了解决苹果强制要求跨域才生效的问题,Universal Link就不能配置在主域名下,于是知乎才会准备一个oia.zhihu.com域名,专为Universal Link使用,不会跟任何主动传播分享的域名撞车,从而在任何活动WAP页面里,都能顺利让Universal Link生效。

简单一句话

只有当前webview的url域名,与跳转目标url域名不一致时,Universal Link 才生效
Universal Link不是必须通过a标签的href来跳转,我遇到一个问题就是我的页面没有识别Universal Link,因为异步渲染页面,导致没有解析出来Universal Link,加了一个隐藏的a标签,href配置上Universal Link,页面里面所有需要跳转Universal Link都会被识别

移动端(ios、android)上传图片遇到的兼容问题

Posted on 2020-06-26 | In Frontend前端 , H5 | 0 comments | Visitors:

最近接了一个需求,需要做上传,框架用多了,本来以为这些东西拿过来直接用就行,但是在开发过程中发现了一些问题:

一、安卓手机上传图片没有拍照选项、ios没有拍照选择相册功能

1、按照以下方式写安卓手机没有拍照选项,只能传图片

1
<input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />

2、按照以下方式写ios手机正常,有选择图片和拍照上传功能,安卓手机大部分没有问题,但是安卓10版本没有拍照上传功能

1
<input type="file" id="choose" accept="image/*"  multiple>

3、按照以下方式写ios手机直接唤起拍照功能,没有选择图片上传功能,(安卓10版本预计可以拍照上传)

1
<input type="file" id="choose" accept="image/*" capture="camera" multiple>

accept表示打开的系统文件目录
capture表示的是系统所捕获的默认设备,
camera:照相机;camcorder:摄像机;microphone:录音;
其中还有一个属性multiple,支持多选,当支持多选时,multiple优先级高于capture,所以只用写成:

二、优化上传图片增加图片上传压缩功能

用canvas压缩图片的原理就是读取图片的文件,然后把图片画在画布上,再用canvas自带的一个接口:

1
canvas.toDataURL(type,encoderOptions);

第二个参数encoderOptions决定了图片压缩的程度,可以在0-1中选择一个值,当然推荐不要低于0.5,因为这样保存后的图片质量不太好。
这个方法执行完后会返回一个值,就是图片的base64格式的字符串,这个字符串就可以上传到服务端。

三、移动端IOS系统手机拍照图片Canvas压缩上传后图片旋转的bug

网上大部分是说exfe.js来读取图片信息,我们上传的图片里面是有很多信息的
这里我们需要拿到Orientation的值有1,3,6,8之类的,分别代表0°,180°,顺时针90°,逆时针90°
Orientation
图片原文

1
2
3
4
5
6
7
8
9
10
11
//获取照片方向角属性,用户旋转控制

EXIF.getData(file, function() {

EXIF.getAllTags(this);

Orientation = EXIF.getTag(this, 'Orientation');

console.log(Orientation);

});

但是,这里正常是我拿到角度之后绘制图片按照角度回正,大部分机器是没有问题的,安卓手机测试了下,什么角度拍照Orientation都为1,IOS的Orientation都是按照角度返回的,但是在IOS13.4版本以后,带有角度上传的图片也不会旋转,所以需要版本号判断IOS13.4以后不做回正处理

1
2
3
4
5
let iosVersion = UserAgent.str.match(/CPU iPhone OS (.*?) like Mac OS/);
if(UserAgent.env.ios && iosVersion && compareVersion([13,4],iosVersion[1].split('_'))<0){
callback(-5);
return
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const canvas = document.createElement('canvas');
canvas.width = width = drawWidth;
canvas.height = height = drawHeight;
const context = canvas.getContext('2d');
//判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
switch (dir) {
//iphone横屏拍摄,此时home键在左侧
case 3:
degree = 180;
startX = - width;
startY = - height;
drawWidth = width;
drawHeight = height;
break;
//iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)
case 6:
canvas.width = height;
canvas.height = width;
degree = 90;
startY = - height;
drawWidth = width;
drawHeight = height;
break;
//iphone竖屏拍摄,此时home键在上方
case 8:
canvas.width = height;
canvas.height = width;
degree = 270;
startX = - height;
drawWidth = width;
drawHeight = height;
break;
default:
}
//使用canvas旋转校正
context.rotate(degree * Math.PI / 180);
//canvas rotate旋转角度是根据原点(0,0)开始旋转的,所以绘制的起始坐标需要改变,并不是一直从0,0绘制
context.drawImage(this, startX, startY, drawWidth, drawHeight);

四、前端上传图片利用canvas水印合成

大体步骤:

用户使用input file上传图片的时候,利用 FileReader ,读取 blob对象 ,或者是 file对象 ,将图片转化为 data uri (base64格式)的形式。
使用 canvas ,在页面上新建一个画布,利用 canvas 提供的API,将图片画入这个画布当中。
利用 canvas.toDataURL() ,进行图片的压缩,得到图片的 data uri 的值,用来上传。
获取到压缩后的base64格式图片数据,转成二进制塞入formdata,再通过XmlHttpRequest提交formdata。

参照文章
参照文章
参照文章水印合成

移动开发h5表单键盘弹出问题

Posted on 2020-04-09 | In Frontend前端 , H5 | 0 comments | Visitors:

最近在做移动端开发,每过一段时间,发现又出现新的兼容问题,这次也不例外。

ios手机

之前ios手机是没有问题的,昨天测试的时候发现键盘弹出不会有遮挡input表单的问题,但是输入完成,键盘收回后发现,页面会有一个空白位置没有收回
键盘收回.jpeg

键盘弹出.jpeg
可以在失去input焦点blur的时候用scrollTo做个处理还原页面的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function getPlat() {
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //判断是否是 android终端
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //判断是否是 iOS终端
if (isAndroid) {
return 'Android';
} else if (isIOS) {
return 'IOS';
} else {
return 'PC';
}
}
if (getPlat() === 'IOS') {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 0);
}

Android手机(测试机有oppo、华为、三星、锤子)

但是在Android 手机中就没有这么容易了,测试发现,安卓手机中如果不做任何处理,弹出的键盘会遮盖输入框,但是键盘弹出后手动滚动页面,收回键盘,在聚焦弹出键盘就会定位到上次滚动的地方。其实这样也还好,但是测试要求想要自动展示到键盘上方。所以我需要做些兼容处理
经检测有几种解决办法:
一、修改输入登录模块的定位用fixed、会跟着键盘一起动,可以在聚焦失焦给样式做些处理,但是会麻烦一些
二、scrollIntoView 与 scrollIntoViewIfNeeded API
可以在页面挂载完成mounted的时候做处理,统一对所有的input和textarea做处理

1
2
3
4
5
6
7
8
9
if ((/Android/gi).test(navigator.userAgent)) {
window.addEventListener('resize', function () {
if (document.activeElement.tagName == 'INPUT' || document.activeElement.tagName == 'TEXTAREA') {
window.setTimeout(function () {
document.activeElement.scrollIntoViewIfNeeded();
}, 0);
}
});
}

或者在input聚焦focus的时候做处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<template>
<input
v-model="codeValue"
type="text"
placeholder="请输入收到的验证码"
class="verify-input"
maxlength="6"
@focus="changefocus"
@blur.prevent="blur"
>
</template>
<script>
export default {
methods: {
blur(){
if (judgeClient() === 'IOS') {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 0);
}
},
changefocus() {
if (this.getPlat() === 'Android') {
setTimeout(() => {
el.target.scrollIntoViewIfNeeded(true);
el.target.scrollIntoView(true);
}, 200);
}
},
getPlat() {
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //判断是否是 android终端
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //判断是否是 iOS终端
if (isAndroid) {
return 'Android';
} else if (isIOS) {
return 'IOS';
} else {
return 'PC';
}
}
}
}
</script>

安卓手机有延迟,有时生效,有时会失效,可能setTimeout设置的延迟事件不够,我设置100的时候还会经常没生效,但是设置200貌似就好很多

JavaScript、vue中控制滚动条位置(以及安卓手机中遇到的坑)

Posted on 2020-04-09 | In Frontend前端 , H5 | 0 comments | Visitors:

最近做了一个需求的,其中有一个效果是点击按钮将表单滚动到可视区域,这本来是很常见的效果。我们有很多种方案去实现。
一、 scrollTo、scroll or scrollBy
image.png
这显示不支持safari on ios ,但是我的手机版本是13.3.1的safari可以运行没有问题,但是安卓手机完全无效果

1
2
3
4
5
6
7
8
9
window.scrollTo({
top: 1000,
left: 100,
behavior: 'smooth'
});
document.body.scrollTo({
top: 1000,
behavior: 'smooth'
});

vue中可以根据ref来操作dom

1
2
3
4
this.$refs.xxx.$el.scrollTo({
top: 1000,
behavior: 'smooth'
});
1
2
3
4
5
6
window.scroll({
top: 100,
left: 100,
behavior: 'smooth'
});
document.body.scrollBy(0, 1000);

二、scrollTop 获取当前页面的滚动条纵坐标位置去改变其值

  • 对于没有doctype声明的页面里可以使用 document.body.scrollTop 来获取 scrollTop高度 ;
  • 对于有doctype声明的页面则可以使用 document.documentElement.scrollTop; Safari
  • safari 比较特别,有自己获取scrollTop的函数 : window.pageYOffset ; Firefox
  • 火狐等等相对标准些的浏览器就省心多了,直接用 document.documentElement.scrollTop ;

浏览器和ios都可以生效,但是安卓手机手机完全无效果,测试了一下,安卓手机设置完scrollTop再去console出scrollTop的值,发现并没有赋值成功

1
document.body.scrollTop = document.documentElement.scrollTop = window.pageYOffset = 1000;

三、scrollIntoView 与 scrollIntoViewIfNeeded API (安卓、ios手机支持,浏览器测试结果看来也没问题)
Element.scrollIntoView()方法让当前的元素滚动到浏览器窗口的可视区域内。这是一个实验中的功能
image.png

1
2
3
4
5
element.scrollIntoView(true);
或者
element.scrollIntoView({behavior: "instant", block: "start", inline: "nearest"});
vue中
this.$refs.xxxx.$el.scrollIntoView();

Element. scrollIntoViewIfNeeded()
如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。 此方法是标准的Element.scrollIntoView()方法的专有变体。非标准 该特性是非标准的,请尽量不要在生产环境中使用它!
image.png

1
element. scrollIntoViewIfNeeded(true);

vue中根据ref来操作dom

1
this.$refs.xxxx.$el. scrollIntoViewIfNeeded();

Window.pageYOffset

image.png

监听,取消监听滚动事件
注意scroll监听的匿名事件是不可以取消监听事件的,我想要的是页面中所有需要曝光的地方曝光结束后,取消监听事件
可以参照埋点之眼球曝光

1
2
3
4
5
window.addEventListener('scroll', this.handleScroll);
window.removeEventListener('scroll', this.handleScroll);
const handleScroll = () => {
console.log(111111)
}

移动端Charles抓取https包

Posted on 2020-03-03 | In Tools , Charles | 0 comments | Visitors:

一、安装charles抓包工具
二、配置Charles,允许抓取https包
Proxy->SSL Proxying Settings…,勾选Enable SSL Proxying,Add一个locations,通过通配符* 抓取所有域名的https。(如果想只抓取某个域名的,设置具体域名的即可)
image.png
image.png
三、PC端Charles安装https证书
Help->SSL Proxying ->Install Charles Root Certificate,然后在钥匙串中信任证书即可

如果想要抓取pc端的接口请求勾选上macOS proxy就可以了
image.png

四、手机端手机端配置PC的代理并下载Charles的证书
首先需要手机连接到与当前电脑同一个wifi局域网,对该wifi网络进行高级设置-代理:
代理服务器主机名:使用PC的本机IP地址
代理服务器端口:使用Charles设置的Port值,默认是8888,可以在下图proxy Settings查看端口号
image.png
image.png
然后确定保存,第一次配置完代理,PC端会弹窗询问是否允许代理,点击allow
image.png

这时我们的手机就已经挂上代理了。你也可以这么通过add添加
image.png
image.png

挂上代理了之后手机端需要在浏览器中访问chls.pro/ssl 下载证书
www.charlesproxy.com/getssl/
image.png
image.png
ios10以上系统不会自动信任证书,需要在设置->通用->关于本机,信任安装的证书

现在客户端环境下,我们已经可以随时调试本地的H5代码了。
Charles结合nginx和ihost开发,在nginx代理的时候在开启charles用手机访问开发文件可能访问不到,可能是自制证书不信任的问题,需要对nginx和chrome做特殊处理
设置本地 nginx 的 HTTPS(证书设置信任)

Nginx之OCSP stapling配置

Posted on 2020-03-03 | In nginx | 0 comments | Visitors:

OCSP stapling是Https优化方案之一,将原本需要客户端实时发起的 OCSP 请求转嫁给服务端;

  • 在线证书状态协议(Online Certificate Status Protocol),简称 OCSP,是一个用于获取 X.509 数字证书撤销状态的网际协议,在 RFC 6960 中定义。OCSP 用于检验证书合法性,查询服务一般由证书所属 CA 提供。OCSP 查询的本质,是一次完整的 HTTP 请求加响应的过程,这中间涵括的 DNS 查询、建立 TCP 连接、Web 端工作等步骤,都将耗费更多时间,使得建立 TLS 花费更多时长。
  • OCSP存在隐私和性能问题。
    1、浏览器直接去请求第三方CA(Certificate Authority, 数字证书认证机构),会暴露网站的访客(CA 机构会知道哪些用户在访问我们的网站);
    2、浏览器进行OCSP查询会降低HTTPS性能(访问我们的网站会变慢) OCSP实时查询会增加客户端的性能开销。

后来,OCSP Stapling 出现了。将原本需要客户端实时发起的 OCSP 请求转嫁给服务端,Web 端将主动获取 OCSP 查询结果,并随证书一起发送给客户端,以此让客户端跳过自己去寻求验证的过程,提高 TLS 握手效率。 可以提高HTTPS性能。

在线校验
  • 此方式需要支持服务器能够主动访问证书校验服务器才能生效,并且在每次重启nginx的时候会主动请求一次,如果网络不通会导致nginx启动缓慢。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    server {
    listen 443 ssl;
    server_name xx.xx.com;
    index index.html index.htm index.jsp;

    ssl_certificate server.pem;#证书的.cer文件路径
    ssl_certificate_key server-key.pem;#证书的.key文件

    # 开启 OCSP Stapling ---当客户端访问时 NginX 将去指定的证书中查找 OCSP 服务的地址,
    获得响应内容后通过证书链下发给客户端。
    ssl_stapling on;
    ssl_stapling_verify on;# 启用OCSP响应验证,OCSP信息响应适用的证书
    ssl_trusted_certificate /path/to/xxx.pem;#若 ssl_certificate 指令指定了完整的证书链,则 ssl_trusted_certificate 可省略。
    resolver 8.8.8.8 8.8.4.4 216.146.35.35 216.146.36.36 valid=60s;#添加resolver解析OSCP响应服务器的主机名,valid表示缓存。
    resolver_timeout 2s;# resolver_timeout表示网络超时时间
    人工更新
    为了缓存的更新时间更可加控,你也可以人工负责更新文件内容。利用 NginX 的 ssl_stapling_file 指令直接将 OCSP 响应存成文件,NginX 从文件获取OCSP响应而无需从服务商拉取,将其随证书下发而不实时查询。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    server {
    listen 443 ssl;
    server_name xx.xx.com;
    index index.html index.htm index.jsp;

    ssl_certificate server.pem;#证书的.cer文件路径
    ssl_certificate_key server-key.pem;#证书的.key文件

    # 开启 OCSP Stapling ---当客户端访问时 NginX 将去指定的证书中查找 OCSP 服务的地址,
    获得响应内容后通过证书链下发给客户端。
    ssl_stapling on;
    ssl_stapling_file /xxx/xxx/stapling_file.ocsp;
    ssl_stapling_verify on;# 启用OCSP响应验证,OCSP信息响应适用的证书
    ssl_trusted_certificate /path/to/xxx.pem;#若 ssl_certificate 指令指定了完整的证书链,则 ssl_trusted_certificate 可省略。
    参考博客-配置
    参考博客-https优化

nginx配置允许指定域名下所有二级域名跨域请求

Posted on 2020-03-03 | In nginx | 0 comments | Visitors:

跨域资源共享 CORS
核心原理是根据请求域名匹配是否是某域名的二级域名判断是否添加允许跨越头。
比如你想设置amy.com和kk.com下的子域名都可以跨域方案
需要在请求不能设置*
可以用nginx用$http_origin这样配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
server {
listen 443 ssl;
server_name xxx.xxx.com;
index index.html index.htm index.jsp;

ssl_certificate /server.pem;#证书的.cer文件路径
ssl_certificate_key /server-key.pem;#证书的.key文件
set $flag '0';
location / {
if ($http_origin ~* "(https?:\/\/.*\.amy\.com($|\/))") {
set $flag '1';
}
if ($http_origin ~* "(https?:\/\/.*\.kk\.com($|\/))") {
set $flag '1';
}
if ($flag = '1') {
#add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Origin "$http_origin";
###带上用户认证信息
add_header Access-Control-Allow-Credentials true;
##允许的方法post,get
add_header Access-Control-Allow-Methods "POST, GET, PUT, PATCH, DELETE";
add_header Access-Control-Allow-Headers "xxx-xx-xx";
}
proxy_pass http://all_domians_default_http_upstream;#转向tomcat处理
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Scheme $scheme;#将scheme协议头发送给tomcat
}
}

Nginx能为前端带来什么(分享)

Posted on 2020-03-03 | In nginx | 0 comments | Visitors:

一、利用Nginx和Host把自定义域名指向本地


移动互联网发展到今天,我们的前端开发工作内容已不仅仅局限于pc浏览器端的网页,现在很多应用都已经引入了新的开发模式:Hybrid APP 或者 H5页面开发

本地切页面mock数据开发阶段实时调试方法很简单:

1
2
3
1. 先确保你的手机和电脑连在同一个局域网内. 
2. 打开terminal, 然后输入 ipconfig,然后获取ip地址 192.168.XX.XX
3. 手机浏览器里输入这个地址: http://192.168.XX.XX:8080就可以访问到了

但是我们考虑一下以下场景
在测试环境联调接口的时候,虽说是和后端商量好了接口定义和返回数据,在上测试环境之前,本地开发的时候可以访问测试环境的数据就好了,方便我们自测
在线上环境如果出现bug,我们没有客户端的真实环境,比如测试环境没有正式环境的某些数据,很难将问题复现出来,也不可能拿线上代码直接去push调试,所以这种方案显然不合理。那么有什么办法能让我们修改完本地代码后,直接重载客户端的Webview,就能实时看到Native中最新效果了呢。

1.如何本地调取线上环境接口数据,没数据我们无法测试

下面我们就用nginx和host 把自定义域名指向本地
mac 安装nginx 并用Nginx和Host把自定义域名指向本地实现Https访问
mac openssl生成你需要的域名的证书并且设置信任证书

2.如何将本地代码实时同步到客户端内访问。
这个时候需要charles
移动端Charles抓取https包
首先需要手机连接到与当前电脑同一个wifi局域网,对该wifi网络进行高级设置-代理:
代理服务器主机名:使用PC的本机IP地址
代理服务器端口:使用Charles设置的Port值,默认是8888
如果不能访问开发页面可以参照移动端Charles抓取https包最后说的证书的问题

npm包里面http-proxy-middleware也是可以实现的

openssl生成证书并设置本地 Nginx 的 HTTPS(证书设置信任)

Posted on 2020-03-03 | In nginx | 0 comments | Visitors:

创建密钥

首先,进入 nginx 配置目录,创建 openssl 配置文件 req.conf,其中的 CN, DNS.1, DNS.2 等需要替换为自己的域名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = VA
L = SomeCity
O = MyCompany
OU = MyDivision
CN = www.company.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.company.net
DNS.2 = company.com
DNS.3 = company.net

接着,执行如下命令,创建证书:

1
openssl req -x509 -nodes -days 730 -newkey rsa:2048 -keyout cert.pem -out cert.pem -config req.conf -extensions 'v3_req'

配置nginx

1
2
3
4
5
6
7
8
9
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate cert.pem;
ssl_certificate_key cert.pem;
location / {
root /Users/example/hello/world;
index index.html index.htm;
}

服务器证书(ssl_certificate)是一个公开文件,每个请求连接的客户端都会收到一份。私有密钥(ssl_certificate_key)是加密单元,需要存储在保密的地方,但要确保 nginx 主线程可访问。私有密钥一般和证书存储到同一位置。

cert.pem 就是上一个步骤产生的证书和密钥,在一个文件中。

配置浏览器

打开 Chrome 的开发者工具下的【security】选项卡,查看当前的证书,然后下载下来,双击添加到操作系统中,修改为始终信任就可以了。

如果还继续显示是不安全,像下图这样
image.png

可以参照以下解决办法
Open developer tools
Goto the Application tab
Clear storage
Close and re-open tab

详细问题参照 “Active content with certificate errors”

<1234>
Amy Chen

Amy Chen

All problems in computer science can be solved by another level of indirection. -by David John Wheeler

36 posts
28 categories
31 tags
RSS
GitHub E-Mail Skype 简书
© 2021 Amy Chen
Powered by Hexo
|
Theme — NexT.Pisces v5.1.4