JavaScript 深入之执行上下文

2017/05/18 · JavaScript
·
执行上下文

原文出处: 冴羽   

你所不知道的 HSTS

2015/10/24 · HTML5 ·
HSTS

原文出处:
李靖(@Barret李靖)   

很多人听说过也看到过 301、302,但是几乎从来没有看到过 303 和 307
的状态码。今天在淘宝首页看到了 307 状态码,于是摸索了一把。

网页程序迁移至微信小程序web-view详解

2018/08/02 · JavaScript
· 小程序

原文出处: NeoPasser   

小程序现在越来越流行,但是公司的很多项目都是用网页写的,小程序语法不兼容原生网页,使得旧有项目迁移至小程序代价很高。

小程序之前开放了webview功能,可以说是网页应用的一大福音了,但是微信的webview有一些坑,这篇文章就是列举一下我在开发过程中遇到的一些问题以及我找到的一些解决方案。

前言

在《JavaScript深入之执行上下文栈》中讲到,当JavaScript代码执行一段可执行代码(executable
code)时,会创建对应的执行上下文(execution context)。

对于每个执行上下文,都有三个重要属性:

  • 变量对象(Variable object,VO)
  • 作用域链(Scope chain)
  • this

然后分别在《JavaScript深入之变量对象》、《JavaScript深入之作用域链》、《JavaScript深入之从ECMAScript规范解读this》中讲解了这三个属性。

阅读本文前,如果对以上的概念不是很清楚,希望先阅读这些文章。

因为,这一篇,我们会结合着所有内容,讲讲执行上下文的具体处理过程。

中间人劫持

起因是这样,https 使用的是 443 端口进行数据传输,而浏览器的默认端口是

  1. 劫持者首先劫持用户的 80
    端口,当用户向目标页发起请求时,劫持者模拟正常的 https
    请求向源服务器获取数据,然后通过 80
    端口返回给用户,大概可以看下下面两张图:

澳门微尼斯人手机版 1

用户一般不会在地址栏输入   ,而是习惯性输入
taobao.com  ,此时浏览器走的是
http,请求到达服务器之后,服务器告诉浏览器 302 跳转

Location:

1
Location: https://www.taobao.com

然后浏览器重新请求,通过 HTTPS 方式,443
端口通讯。而正因为用户不是直接输入 https:// 链接,劫持者利用这一点:

澳门微尼斯人手机版 2

只要能够劫持你的网络,比如路由劫持、DNS劫持,就可以作为中间人注入代码、替换广告。。。(上了
https 也拗不过电信,真是日了够了)

这种劫持出现在两种情况下:

  • 用户没有通过准确的方式访问页面,除非输入 https:// ,否则浏览器默认以 http 方式访问
  • HTTPS 页面的链接中包含 http,这个 http 页面可能被劫持

遇到的问题

  1. openid登录问题
  2. webview动态src
  3. 支付功能
  4. 分享功能
  5. 扫描普通二维码跳转特定页面
  6. 返回按钮缺失问题

思考题

在《JavaScript深入之词法作用域和动态作用域》中,提出这样一道思考题:

var scope = “global scope”; function checkscope(){ var scope = “local
scope”; function f(){ return scope; } return f(); } checkscope();

1
2
3
4
5
6
7
8
9
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
checkscope();

var scope = “global scope”; function checkscope(){ var scope = “local
scope”; function f(){ return scope; } return f; } checkscope()();

1
2
3
4
5
6
7
8
9
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()();

两段代码都会打印’local
scope’。虽然两段代码执行的结果一样,但是两段代码究竟有哪些不同呢?

紧接着就在下一篇《JavaScript深入之执行上下文栈》中,讲到了两者的区别在于执行上下文栈的变化不一样,然而,如果是这样笼统的回答,依然显得不够详细,本篇就会详细的解析执行上下文栈和执行上下文的具体变化过程。

启用 HSTS

HSTS,HTTP Strict Transport
Security,简单说就是强制客户端使用 HTTPS 访问页面。其原理就是:

  • 在服务器响应头中添加  Strict-Transport-Security ,可以设置  max-age
  • 用户访问时,服务器种下这个头
  • 下次如果使用 http 访问,只要 max-age
    未过期,客户端会进行内部跳转,可以看到 307 Redirect Internel
    的响应码
  • 变成 https 访问源服务器

这个过程有效避免了中间人对 80
端口的劫持。但是这里存在一个问题:如果用户在劫持状态,并且没有访问过源服务器,那么源服务器是没有办法给客户端种下
Strict-Transport-Security  响应头的(都被中间人挡下来了)。

启用 HSTS 不仅仅可以有效防范中间人攻击,同时也为浏览器节省来一次 302/301
的跳转请求,收益还是很高的。我们的很多页面,难以避免地出现 http
的链接,比如 help 中的链接、运营填写的链接等,这些链接的请求都会经历一次
302,对于用户也是一样,收藏夹中的链接保存的可能也是 http 的。

openid登录问题

微信webview的使用方法很简单,只要如下设置src就可以展示具体的网站了。

澳门微尼斯人手机版,<!– wxml –> <!– 指向微信公众平台首页的web-view –>
<web-view src=”;

1
2
3
<!– wxml –>
<!– 指向微信公众平台首页的web-view –>
<web-view src="https://mp.weixin.qq.com/"></web-view>

微信环境里的很多网页都是用页面要实现网站的登录功能,只要把登录的信息,比如openid或者其他信息拼接到src里就好了。

这里有个问题,公众号的账号体系一般是以openid来判断唯一性的,小程序是可以获取openid的,但是小程序的openid和原公众号之类的openid是不一样的,需要将原先的openid账号体系升级为unionid账号体系。

以下是微信对unionid的介绍

获取用户基本信息(UnionID机制)

在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。

请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

UnionID机制说明:

开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

做完以上步骤,就可以调用小程序api wx.getUserInfo()
来获取用户信息了,此步骤需要进行后台信息解密过程,在此就不再赘述,结合小程序api文档操作就好。

获取到unioid之后,将unionid信息拼接到src就可以进行网页登录操作了(前提是网页可以用跳转链接的方式登录,类似公众号页面获取openid的形式)。

发表评论

电子邮件地址不会被公开。 必填项已用*标注