{"action":"created","issue":{"url":"https://api.github.com/repos/riskers/blog/issues/11","labels_url":"https://api.github.com/repos/riskers/blog/issues/11/labels{/name}","comments_url":"https://api.github.com/repos/riskers/blog/issues/11/comments","events_url":"https://api.github.com/repos/riskers/blog/issues/11/events","html_url":"https://github.com/riskers/blog/issues/11","id":115423156,"number":11,"title":"打造最舒适的webview调试环境","user":{"login":"riskers","id":5653652,"avatar_url":"https://avatars.githubusercontent.com/u/5653652?v=3","gravatar_id":"","url":"https://api.github.com/users/riskers","html_url":"https://github.com/riskers","followers_url":"https://api.github.com/users/riskers/followers","following_url":"https://api.github.com/users/riskers/following{/other_user}","gists_url":"https://api.github.com/users/riskers/gists{/gist_id}","starred_url":"https://api.github.com/users/riskers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/riskers/subscriptions","organizations_url":"https://api.github.com/users/riskers/orgs","repos_url":"https://api.github.com/users/riskers/repos","events_url":"https://api.github.com/users/riskers/events{/privacy}","received_events_url":"https://api.github.com/users/riskers/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/riskers/blog/labels/mobile","name":"mobile","color":"5319e7"},{"url":"https://api.github.com/repos/riskers/blog/labels/%E8%B0%83%E8%AF%95","name":"调试","color":"006b75"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-11-06T02:48:30Z","updated_at":"2015-11-06T04:05:50Z","closed_at":null,"body":"你在做移动web开发的时候是不是只是在Chrome下开启移动模式，然后就啪啪啪闷头敲代码了？如果你平时只是做做宣传页，Chrome的移动模式可能就能满足你。但是现在越来越多的应用采用Hybrid的开发方式，这样的话就可能在web页面上调用webview注入的函数，那么，这个页面在Chrome上只会报错，因为我们不在webview里，根本没有注入的那些函数。\r\n\r\n以我现在做的项目为例，要在页面里判断在客户端有没有登录，可以这样写:\r\n\r\n```\r\nvar isLogin = AndroidWebview.hasLogin() ;\r\n```\r\n\r\n结果可想而知，AndroidWebview是客户端在webview里注入的方法，这里当然会报错了。\r\n\r\n![webview-error](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-5/2912379.jpg)\r\n\r\n## 真机测试\r\n这种情况怎么开发呢？回顾一下以前的两种办法 :\r\n\r\n* 真机 + Chrome inspect ：Chrome 版本必须高于 32，其次你的测试机 Android 系统高于 4.4\r\n\r\n\t1. 先用数据线将 Android 测试机连接到电脑上。需要打开测试机上面“开发者选项”中的 “USB 调试”功能。\r\n\t2. 在PC的Chrome上打开`Chrome://inspect`即可找到你的设备\r\n\t3. 手机进入一个webview页面，即可在Chrome上看到调试台了\r\n\r\n\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-5/28429695.jpg)\r\n\t\r\n\t可以看到，第一个记录是手机里的浏览器的；第二个是记录是手机助手里的webview。\r\n\r\n* 真机 + weinre : 在你本地创建一个监听服务器，并提供一个JS脚本，需要在需要测试的页面中加载这段 JS，就可以被 Weinre 监听到，在 Inspect 面板中调试你这个页面。\r\n\t\r\n\t1. 安装 weinre `npm install -g weinre`\r\n\t2. 开启 weinre `weinre --httpPort 8888 --boundHost -all-`\r\n\t3. 浏览器打开 `localhost:8888` :\r\n\t\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-5/36030683.jpg)\r\n\t4. 将 \"2\" 这段脚本加载到调试的页面最后，手机进入页面，然后进入 \"1\" ，就可以看到控制台了\r\n\t\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-5/11220086.jpg)\r\n\r\n这两种办法都需要真机测试，你可以想像一下你在开发、调试时的流程：\r\n\r\n1. 写代码\r\n2. 拿起手机，进入页面\r\n3. 有BUG，重复1、2\r\n4. 开发新功能，重复1、2、3\r\n\r\n然后你的手不停地在键盘和手机之间切换，多么痛苦。后来，我遇到了`Genymotion`。\r\n\r\n## Genymotion\r\n这是一款安卓模拟器，有了它我们可以在电脑上开启一个安卓机。具体使用我就不细说了，很简单请自行搜索。\r\n\r\n这是我在模拟器上安装的手机助手：\r\n\r\n![store](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-5/92941591.jpg?imageView/2/w/300)\r\n\r\n而且使用 `Chrome inspect` 是直接可以调试模拟器中的webview的：\r\n\r\n![store-webview](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-5/92941591.jpg?imageView/2/w/300)\r\n\r\n这样，我们就可以不用手忙脚乱地写代码、看手机了，一切都在PC上调试。但是我们在模拟器上看到的是线上代码，我们加一个新功能还要发布代码才能看到效果？\r\n\r\n## Charles / Fiddler\r\n幸好有`Charles`这样的工具(`Windows`下请使用`Fiddler`)，`Charles`会在本地开启一个代理服务，默认接口`8888`。通过这个代理，模拟器上的请求会被转移到电脑上，我们可以任意地去替换请求文件让我们更加方便地调试页面。\r\n\r\n### 设置监听端口\r\n`Proxy Settings` - `HTTP Proxy` - `Proxies` - `HTTP Proxy` 中设置\r\n\r\n### 监听Chrome\r\n因为 `Charles` 只会监听全局和Firefox，为了能监听Chrome，使用[Proxy SwitchyOmega](https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif?utm_source=chrome-ntp-icon)插件，增加一个情景模式：\r\n\r\n![switchyOmega](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/99779359.jpg)\r\n\r\n在这个情景模式下，我们就可以抓到在Chrome里的数据了：\r\n\r\n![sina](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/68809502.jpg)\r\n\r\n注意：Charles默认是不支持https的，我们选择 `设置` - `Proxy Settings` - `SSL` ，选中 `Enable SSL Proxying` 。然后在 `Locations` 里填写要抓包的域名和端口，点击 `Add`，`Host`填写域名，如 www.baidu.com ，`port`填 `443` 。具体参考最后的文章。\r\n\r\n### 监听Genymotion\r\n别忘了，使用Charles的初衷是让我们可以用本地的文件替换线上文件，不用每次修改都要发布。\r\n\r\n1. 在Genymotion中，`Settins` - `Network` (port选`9999`是因为我之前在Charles中设置的是9999) :\r\n\t\r\n\t![settings](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/93993292.jpg)\r\n\r\n2. 在开启的模拟器中，`设置` - `WLAN` - `长按2秒` - `修改网络` ，`代理设置`改为`手动`，主机名为`10.0.3.2`，端口为`9999`，和上面一致。\r\n\r\n3. 然后在模拟器中打开webview页面就可以看到所有请求了\r\n\r\n\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/56828398.jpg)\r\n\r\n4. 右键保存源文件到本地，然后添加一行alert代码 。\r\n\r\n\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/18746003.jpg?imageView/2/w/300)\r\n\t\r\n\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/95690593.jpg)\r\n\r\n5. 在请求上右键，选择 `Map Local`\r\n\t\r\n\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/85809553.jpg?imageView/2/w/300)\r\n\t\r\n6. 选择刚才修改过的文件\r\n7. 重新载入页面 : \r\n\t\r\n\t![](http://7xlc2a.com1.z0.glb.clouddn.com/15-11-6/56739214.jpg?imageView/2/w/300)\r\n\r\n这样，我们利用`模拟器+Chrome+Charles`就可以完美开始、调试webview页面了，模拟器当做手机，`Chrome insepct` 调样式、接口、查看数据，利用`Charles`映射本地文件直接查看效果。\r\n\r\n至于iOS上的webview调试，`模拟器+Safari+Charles`应该也是一样的。我没有试过，试过的人请告知。\r\n\r\n\r\n## 参考\r\n* [浅谈Hybrid技术的设计与实现](http://web.jobbole.com/84121/)\r\n* [移动前端调试页面–weinre](http://web.jobbole.com/82967/)\r\n* [Mac下HTTP/HTTPS抓包工具Charles](http://www.99css.com/1272/)\r\n* [前端开发调试线上代码的两款工具](http://www.cnblogs.com/snandy/p/4934944.html)\r\n"},"comment":{"url":"https://api.github.com/repos/riskers/blog/issues/comments/154279334","html_url":"https://github.com/riskers/blog/issues/11#issuecomment-154279334","issue_url":"https://api.github.com/repos/riskers/blog/issues/11","id":154279334,"user":{"login":"tiann","id":4233744,"avatar_url":"https://avatars.githubusercontent.com/u/4233744?v=3","gravatar_id":"","url":"https://api.github.com/users/tiann","html_url":"https://github.com/tiann","followers_url":"https://api.github.com/users/tiann/followers","following_url":"https://api.github.com/users/tiann/following{/other_user}","gists_url":"https://api.github.com/users/tiann/gists{/gist_id}","starred_url":"https://api.github.com/users/tiann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tiann/subscriptions","organizations_url":"https://api.github.com/users/tiann/orgs","repos_url":"https://api.github.com/users/tiann/repos","events_url":"https://api.github.com/users/tiann/events{/privacy}","received_events_url":"https://api.github.com/users/tiann/received_events","type":"User","site_admin":false},"created_at":"2015-11-06T04:05:50Z","updated_at":"2015-11-06T04:05:50Z","body":"retina上怎么个截屏法，保证在非高清屏上不会扩大两倍？还有，gif录制软件用的啥？"}}