监测移动设备的HTTP请求

在PC上监测web页面的HTTP请求是一件非常简单的事,我们有大量的软件可以来做,甚至浏览器就自带了有这样功能的开发插件。但是在移动设备上就没那么简单了,没有软件,权限控制……下面将介绍2种监测移动设备HTTP请求的方式。

一、使用Charles

在连上WIFI的前提下,android和ios设备都可以通过Charles来监测HTTP请求,原理是通过Charles在PC上架设一个代理,手机访问这个代理,Charles记录网络请求。ios设备,在“设置”-“无线局域网络”里可以直接设置代理,而android没有设置代理的功能,需要取得root权限后安装第三方软件来实现。

操作步骤:

  1. 下载Charles(http://www.charlesproxy.com/download/),安装完成后打开软件
  2. 通过菜单上的“Proxy”-“Proxy Settings…”,进入代理设置见面
  3. “Port”填默认的“8888”即可,勾选“Enable transparent HTTP proxying”,点“OK”确认
  4. 设置手机的代理,端口(Port)写Charles中的端口设置,即“8888”,IP填你PC的IP地址
  5. 用手机发起任意HTTP请求,Charles会弹出一个提示框,点“Allow”,好了HTTP请求都出现在Charles里了

全选所有请求,并选择右侧的“Chart”选项卡就能看到整个HTTP请求瀑布图了:

Android手机设置代理的方式:

  1. 安装“z4root”软件,进入软件后选择第二项,等待一段时间后,自动重启,取得root权限完成
  2. 安装“Transparent Proxy”,进入“Proxy Host”设置PC的IP地址,进入“Proxy Port”设置端口号,即“8888”,勾选“Proxy”,设置完成

二、使用TCPDUMP和Wireshark

Android手机,可以使用TCPDUMP输出网络请求的LOG文件,然后用Wireshark打开该文件,进行统计分析。

操作步骤:

  1. 下载TCPDUMP(http://www.strazzere.com/android/tcpdump),放到D根目录盘下
  2. 下载安装Wireshark(http://www.wireshark.org/)
  3. root手机,方法如上所述
  4. 用usb连上手机
  5. 打开命令行工具CMD,依次输入如下命令:
  6. adb push d:\tcpdump /data/local/tcpdump
  7. adb shell chmod 6755 /data/local/tcpdump
  8. adb shell tcpdump -p -vv -s 0 -w /sdcard/capture.pcap -Z root
  9. 停止抓包:按Ctrl+c
  10. 导出抓包得到的文件到d盘根目录:adb pull /sdcard/capture.pcap d:/
  11. 双击capture.pcap文件,wireshark启动

CodeCola Patterns

CodeCola Patterns is designed to collect and share css code. It’s so free that you can use all patterns for free, and modify all patterns with out register or login. Quality of the shared environment need you and I worked together to protect. With Code Cola, you can share your css code easy, the only thing you have to do is click the share buttonshare. CodeCola Patterns borrow ideas from Subtle Patterns which is a amazing site to collection Photoshop patterns.

CodeCola Patterns是一个用来收集和分享css代码的网站。它非常的自由,你可以免费地使用网站上所有的设计,向全世界分享你的代码,对别的的代码进行改进,而这一切你都无需注册和登录,网站资源的质量需要你我共同维护。通过Code Cola,可以方便地分享你的代码,你唯一需要做的仅仅是按下分享按钮:shareCodeCola Patterns的创意来自Subtle Patterns,它是一个用来分享Photoshop设计的网站。

为什么用英文?

Code Cola85%的用户来至国外,等有时间了再对多语言进行支持。

淘宝招聘前端开发工程师

淘宝招聘前端开发工程师,要求如下:

  1. 已把前端作为自己的职业发展的方向;
  2. 精通各种Web前端技术,包括XHTML/XML/CSS/Javascript/ActionScript等(JS和AS之一即可);
  3. 有基于Ajax或Flash的RIA应用开发经验;
  4. 理解 Web 标准,对可用性、可访问性等相关知识有实际的了解和实践经验;
  5. 至少精通一门非Web前端脚本的语言(如Java/PHP/C++),并有项目经验;
  6. 个性乐观开朗,逻辑性强,对前端有自己的想法,善于和各种背景的人合作;

有意向的同学请发简历至zhanyan@taobao.com

Firebug查看元素

firebug查看元素功能最困难的地方就是当用户点击某个元素的时候,阻止绑定在这个元素上的点击事件,或者当这个元素是一个链接时,阻止链接的释放。也许你首先想到的是鼠标移入的时候,在鼠标底下浮动一个元素,该元素带有1像素的蓝色边框。但这样一来,鼠标事件的e.target就成了底下浮动的元素了。

方法一

比较笨的一个方式是在鼠标的四周各浮动一个元素,分别表示当前元素的四条边,四条边的中间也就是鼠标底下是空的。为了阻止事件、链接的促发,当mousedown的时候,在鼠标底下浮动一个看不见的元素,从而阻断click事件,当mouseup后,又将这个浮动的元素移开,从而让mouseovere.target恢复成鼠标底下的元素。

Demo


var getXY = function(node){
		return {"x": node.getBoundingClientRect().left + Math.max(document.body.scrollLeft, document.documentElement.scrollLeft), "y": node.getBoundingClientRect().top + Math.max(document.body.scrollTop, document.documentElement.scrollTop)};
}
$(document).mouseover(function(e) {
	var target = e.target,
	     width = target.offsetWidth,
	     height = target.offsetHeight,
	     p = getXY(target),
	     x = p.x,
	     y = p.y;
	$('#abs-1').css({"left":x+"px","top":y+"px","width":width+"px","height":0,"border-top":"1px solid blue"});
	$('#abs-2').css({"left":x+width+"px","top":y+"px","width":0,"height":height+"px","border-left":"1px solid blue"});
	$('#abs-3').css({"left":x+"px","top":y+height+"px","width":width+"px","height":0,"border-top":"1px solid blue"});
	$('#abs-4').css({"left":x+"px","top":y+"px","width":0,"height":height+"px","border-left":"1px solid blue"});
});
$(document).mousedown(function(e) {
	$('#abs-mask').css({"left":0,"top":0,"right":0,"bottom":0});
});
$(document).mouseup(function(e) {
	$('#abs-mask').css({"left":0,"top":0,"right":"auto","bottom":"auto"});
});

方法二

第二个方法就比较优雅了,CSS有一个让事件穿透某个元素的属性——pointer-events,有了它我们只需要改变这个属性的值就可以了。当mouseover的时候,属性值为auto,事件可以穿透元素,鼠标的底下浮动的元素就像不存在了一样,e.target始终是我们想要的元素;而当mousedown的时候,将属性值修改为none,让事件不能穿透元素,这样鼠标底下的浮动的元素就阻止了目标元素的click事件;当mouseup后,又将属性值修改为auto

Demo


var getXY = function(node){
		return {"x":node.getBoundingClientRect().left+Math.max(document.body.scrollLeft,document.documentElement.scrollLeft),"y":node.getBoundingClientRect().top+Math.max(document.body.scrollTop,document.documentElement.scrollTop)};
}
$(document).mouseover(function(e) {
	var target = e.target,
	     width = target.offsetWidth,
	     height = target.offsetHeight,
	     p = getXY(target),
	     x = p.x,
	     y = p.y;
	$('#abs-mask').css({"left":x+"px","top":y+"px","width":width+"px","height":height+"px","pointer-events":"none"});
});
$(document).mouseup(function(e) {
	$('#abs-mask').css({"pointer-events":"none"});
});
$(document).mousedown(function(e) {
	$('#abs-mask').css({"pointer-events":"auto"});
});

方法三

第二个方法虽然比第一种幽雅一些,但是当你快速点击的时候,偶尔会失效,不知道是不是事件来不及执行导致的。这里要介绍第三种更加规范、稳定的方法:事件捕获。不了解的朋友可以google一下“事件流”。简单的说,事件有2种传播的方式,一种是我们常用的“事件冒泡”,即当我们点击一个按钮时,这个点击事件,会根据dom结构,一级一级往上传播,直到document对象(chrome、safari、opera、firefox浏览器都将冒泡至window对象);另一种就是“事件捕获”,与前者相反,在事件捕获中,document对象(chrome、safari、opera、firefox都是从window对象开始捕获)首先接受到事件,然后沿着DOM树,依次往下传播,一直到目标按钮,当需要在事件到达目标之前截获时就需要它了,这正是我们需要的。

Demo


var getXY = function(node){
		return {"x":node.getBoundingClientRect().left+Math.max(document.body.scrollLeft,document.documentElement.scrollLeft),"y":node.getBoundingClientRect().top+Math.max(document.body.scrollTop,document.documentElement.scrollTop)};
};
document.documentElement.addEventListener('mouseover', function(e) {
	e.preventDefault();
	var target = e.target,
		width = target.offsetWidth,
		height = target.offsetHeight,
		p = getXY(target),
		x = p.x,
		y = p.y;
	document.getElementById('abs-mask').style.cssText = 'left:'+x+'px;top:'+y+'px;width:'+width+'px;height:'+height+'px;';
}, false);
document.body.addEventListener('click', function(e){
	e.preventDefault();
	e.stopPropagation();
	//console.log(e.target);
}, true);

HTTPS页面包含HTTP资源

在各个浏览器的安全策略中,HTTPS协议页面,不能包含HTTP的资源请求,否则会进行不安全的提示,这篇文章将介绍Https页面包含Http资源相关的一些问题。

各个浏览器的表现

IE6、IE7、IE8

https contains http resource in ie

Firefox

https contains http resource in firefox

Safari

https contains http resource in safari

chrome

https contains http resource in chrome

Opera

有点诡异,再研究下。

激活Fiddler的HTTPS通信解密

因为HTTPS证书的问题(假证书无法通过浏览器的安全验证),很多前端问题我们必须在线上真实环境进行测试,这时候Fiddler的AutoResponder功能就可以大展拳脚了,但Fiddler默认是关闭对于HTTPS资源请求的监测的,需要手动开启。开启步骤:tools > fiddler > https > decrypt https traffic。更详细的请看官方的帮助文档

enable fiddler's https

将所有HTTP资源转化为HTTPS

因为https页面不能包含http资源,所有我们要做的就是将所有http的资源改成https。包括以下内容:

  • 图片 image
  • 样式表 stylesheet
  • 脚本文件 Js
  • Iframe

修改Minify的路径

很多大型网站会使用Minify或者类似的方案来合并资源请求,那么我们就需要修改这个Minify之后的资源的路径。以口碑网为例,Minify路径定义在某个CMS文件中,需要对它进行改写:


//原来的
String result="<link  href=\"http://k.kbcdn.com";

//修改后的
//这里的https的路径仅仅做了一个跳转的功能,实际访问的仍然是"http://k.kbcdn.com"上的资源
String result="<link  href=\"https://login.koubei.com/kbcdn";

CSS背景图片

除了样式表的资源要改成HTTPS,它里面的css背景也需要改成HTTPS的,那么难道我们要把所有的背景修改成background:url(https://login.koubei.com/xxx);吗?当然不是,因为我们已经把css文件修改成了HTTPS的路径,那么我们只要确保我们的background规则中的图片路径是一个相对路径就可以了,浏览器会将它们解析成一个HTTPS的资源请求。

这里需要说明的是Minfy会自动将相对路径改成相对于根目录的绝对路径,比如../img/login.png经过转化后可能是/product/login/v2/img/login.png,浏览器经过解析,得到https://login.koubei.com/product/login/v2/img/login.png,然后再进行一次跳转到http://k.kbcdn.com/product/login/v2/img/login.png。当然这种2层跳转的做法实在是太恶心了。


Selector{
    background:url(../img/login.png) no-repeat 0 0;
}

修改JS Loader的config

以YUI Combo为例,当我们使用use方法异步加载各种资源文件的时候,YUI会根据YUI_config中的资源路径,来生成一个Combo后的资源路径。一般网站都会有一个整站的配置,例如口碑的配置放在seed.js中,为此我们需要在自己的项目中重新配置一个YUI_config来覆盖整站的配置,方法如下:


YUI_config.base = "https://login.koubei.com/kbcdn/yui/3.2.0/";
YUI_config.comboBase = "https://login.koubei.com/kbcdn/min/f=";
//口碑k2框架的资源路径
YUI_config.groups.K2.base = "https://login.koubei.com/kbcdn/k2/";

Data URI

Data URI是一个减少http请求,降低前端工作量的好东西,口碑早已通过自动化的方式在整站使用。但是很可惜,在HTTPS的环境下,IE6、IE7无法使用Data URI。不光mhtml的资源会导致IE6/7报安全提示(即使你已经把它转化成了HTTPS的路径)– This page contains both secure and nonsecure items. Do you want to display the nonsecure items?,甚至用于其它浏览器的base64编码也将导致IE6/7报安全提示。


/*两者都将导致IE6、7报安全提示*/
Selector{
    background:url(data:image/png;base64,iVBORw0…) no-repeat 0 0;
   *background:url(mhtml:https://login.koubei.com/kbcdn/product/login/v2/css/login-1-0-0-mhtml.css!tab.png) no-repeat 0 0;
}

/*改成图片就ok了*/
Selector{
    background:url(../img/login.png) no-repeat 0 0;
}