Total Pageviews

Showing posts with label web 开发资源. Show all posts
Showing posts with label web 开发资源. Show all posts

Friday, 22 July 2022

熟练掌握这些Github项目,让你的Web开发速度提升十倍

Github上有不少开源的项目,观看这些开源代码,可以从中学到不少开发技巧,让你在开发应用的过程中受益匪浅,伯衡君就从中找到了一些对于Web开发者来说非常有益处的项目,如果熟练掌握这十几个项目,可以让你的开发能力乘以10倍?不相信?请看本篇详情。


内容详情

https://github.com/vasanthk/how-web-works
https://github.com/kamranahmedse/developer-roadmap
https://github.com/microsoft/Web-Dev-For-Beginners        关于 JavaScript、CSS 和 HTML 基础知识的 12 周、24 节课的优质课程。每节课都包括课前和课后测验、完成课程的书面说明、解决方案、作业等。

https://github.com/wesbos/JavaScript30  JavaScript 30 天挑战的完整解决方案。
         
https://github.com/apptension/developer-handbook  关于如何成为专业的 Web/移动应用程序开发人员的指南。

https://github.com/dexteryy/spellbook-of-modern-webdev   现代 JavaScript Web 开发的大图、词库和分类法。
https://github.com/google/WebFundamentals    由 Google 开发人员提供的现代 Web 开发的一些最佳实践。
     
https://github.com/airbnb/javascript  最好的风格指南之一。
https://github.com/ryanmcdermott/clean-code-javascript  软件工程原理,来自 Robert C. Martin 的书“清洁代码”,适用于 JavaScript。使用 JavaScript 生成可读、可重用和可重构软件的指南。
       
https://github.com/donnemartin/system-design-primer    了解如何设计大型系统,准备系统设计面试。
     
https://github.com/samdutton/simpl    HTML、CSS 和 Javascript 的最简单示例。
     
https://github.com/gothinkster/realworld  Realworld 允许您选择任何前端(React、Vue 等)和任何后端(Node、Django 等),看看它们如何为现实世界中设计精美的全栈应用程序提供支持。
       
https://github.com/codecrafters-io/build-your-own-x
https://github.com/jwasham/coding-interview-university  成为软件工程师的完整计算机科学学习计划。
       
https://github.com/yangshun/front-end-interview-handbook    为忙碌的工程师准备的前端面试准备材料。
     
https://github.com/yangshun/tech-interview-handbook  为忙碌的工程师准备的前端面试准备材料。
       
https://github.com/bradtraversy/design-resources-for-developers    来自库存照片、Web 模板、CSS 框架、UI 库、工具等的设计和 UI 资源的精选列表。
     
https://github.com/EbookFoundation/free-programming-books  免费提供的编程书籍。
      
https://github.com/cheatsheet1999/FrontEndCollection  前端软件工程师的注意事项。涵盖常见的数据结构和算法、基本的网络概念、HTML & CSS & Javascript。
       

Wednesday, 3 June 2020

科学的 Web 调试代理实践


前端经常需要一些特殊的调试环境,这时有一个科学的 Web 调试代理工具(以下称代理工具)显得尤其重要
我用的第一个代理工具是 Charles,功能多但缺点也很明显,笨重、配置麻烦,爬
后来换到了 Zan Proxy
Zan Proxy 是一个 Node.js 编写的代理工具,跟大杂烩 Charles 不一样,专注于 Web 调试,轻量、配置方便,虽然功能很简单,但对我来说够用了
配置都是在一个 Web 页进行,界面很舒服,我用它做一些简单的转发请求、修改响应头、mock 数据
但随着工作内容的发展,需要的调试环境也越来越复杂,Zan Proxy 已经慢慢不能满足我的需求
 
LightProxy 适时地出现在了我的视野
LightProxy 是一款基于 whistle 的本地代理抓包软件(其实直接用 whistle 也差不多
下面通过一些我自己使用的规则来介绍它
请求转发
1
2
3
4
player.bilibili.com http://127.0.0.1:8080

^*s1.hdslb.com/bfs/static/player/main/video*.js file:///Users/diygod/Code/bilibili/js-common/packages/video/dist/release/video.js
^*s1.hdslb.com/bfs/static/player/main/video*.js.map file:///Users/diygod/Code/bilibili/js-common/packages/video/dist/release/video.js.map
(1)项目接口和 CDN 都被限制某些域名可以用,所以需要这样一个东西做开发环境
比用 webpack 开一个 80 端口的 server 再绑 hosts 优雅 80 倍
(2)可以用来代理线上文件
把本地编译好的项目文件代理到真实线上环境,这里用到了通配符来匹配路径
修改响应内容
1
2
3
4
m.bilibili.com resAppend://`


`
修改移动端页面的响应内容,让页面加载调试工具 Eruda,方便移动端调试
值得一提的是 whistle 有个很神经病的地方,whistle 本身并不支持这样的行内写法,需要很麻烦地在另一个面板设置 {key} 或者使用本地文件
所以 LightProxy 做了一层转义,把行内代码保存成了一个临时文件,打开 whistle 可以看到实际发给 whistle 的配置是类似这样的
1
m.bilibili.com resAppend:///var/folders/_l/hbcxcqh522s_vls68417h2m40000gn/T/lightproxy/0-152.txt
修改响应头
1
2
3
4
5
6
7
8
9
/.*bilivideo\.com\/.*300(\d){2}\.m4s/ resHeaders://`{
    'x-service-module': 'test-video'
}`
/.*bilivideo\.com\/.*302(\d){2}\.m4s/ resHeaders://`{
    'x-service-module': 'test-audio'
}`
/.*bilivideo\.com\/.*\.flv/ resHeaders://`{
    'x-service-module': 'test-flv'
}`
这里用了正则来给不同类型的文件匹配不同的规则
修改 cookie
1
2
3
m.bilibili.com/video/ resCookies://`{
    ab: '0000test',
}`
在移动端修改 cookie 并不是那么方便,所以我用了这个规则,本质上是修改响应头的 Set-Cookie
host 转发
1
172.22.33.166 s1.hdslb.com player.bilibili.com static.hdslb.com
除了支持各种匹配模式,还支持传统 hosts 语法规则,SwitchHosts 可以扔掉了
模拟网络异常
1
2
3
4
5
*.bilivideo.com replaceStatus://403 includeFilter://m:get

*.bilivideo.com resSpeed://2000

*.bilivideo.com resDelay://3000
各种模拟网络异常的功能深深戳中了我的痛点
例子中的 *.bilivideo.com 匹配 bilibili 视频 CDN 地址
(1)模拟 CDN 状态码,用来调试 CDN 地址超时或异常,没有 LightProxy 的日子里只能在代码里 mock 或很蠢地等很久等视频地址超时
(2)模拟慢速,用来调试卡顿或自动清晰度切换,可以用来代替 Chrome Network Throttling
(3)模拟 CDN 请求超时,用来调试 CDN 拉流超时,没有 LightProxy 的时候只能小心翼翼地控制 Chrome Network Throttling,太小了会导致请求失败,太大了超时又不够长
Node.js 规则
LightProxy 还有一个很酷的功能,使用 Node.js 书写规则,以下是官方的一个 demo,我暂时还没有这个功能的使用场景,但就是感觉很酷
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
github.com/alibaba/lightproxy scriptfile://`

exports.handleRequest = async (ctx, next) => {
   // do sth
   // ctx.fullUrl 可以获取请求url
   // ctx.headers 可以获取请求头
   // ctx.options 里面包含一些特殊的请求头字段,分别可以获取一些额外信息,如请设置的规则等
   // ctx.method 获取和设置请求方法
   // const reqBody = await ctx.getReqBody(); 获取请求body的Buffer数据,如果没有数据返回null
   // const reqText = await ctx.getReqText();  获取请求body的文本,如果没有返回''
   // const formData = await ctx.getReqForm(); 获取表单对象,如果不是表单,返回空对象{}
   // ctx.req.body = String| Buffer | Stream | null,修改请求的内容
   // next方法可以设置next({ host, port });
   // 只有执行next方法后才可以把正常的请求发送出去
   const { statusCode, headers } = await next(); 
   // do sth
   // const resBody = yield ctx.getResBody();
   // const resText = yield ctx.getResText();
   // ctx.status = 404; 修改响应状态码
   // ctx.set(headers); 批量修改响应头
   // ctx.set('x-test', 'abc'); 修改响应头
   // ctx.body = String| Buffer | Stream | null; 修改响应内容
   ctx.body = 'test';
 };`
从以上例子中相信大家已经对 LightProxy / whistle 的用法有了自己的理解
 
最后还有一个值得一提的事情是,用了这些调试代理工具之后魔法上网怎么办?
调试和魔法上网用的是不同的代理,我是一个面向 Google 编程的人,代理一直切来切去太麻烦,我的做法是系统代理交给 Surge 接管,利用 Surge 分流,新建一个 LightProxy 代理,然后编辑 Surge 规则,只把需要调试的请求分给 LightProxy
以上就是我目前的 Web 调试代理实践.

Friday, 10 June 2016

WebApp的调试工具-Weinre

什么是 weinre?

weinre官网 上有两句有意思的介绍:
weinre is WEINspector REmote. Pronounced like the word “winery”. Or maybe like the word “weiner”. Who knows, really.
weinre is a debugger for web pages, like FireBug (for FireFox) and Web Inspector (for WebKit-based browsers), except it’s designed to work remotely, and in particular, to allow you debug web pages on a mobile device such as a phone.
上面说 weinre 是一个远程 web 调试器。说到了它的发音,还挺幽默,哈哈。
远程 web 调试器。先说调试器,就像火狐中的 FireBug,Chrome 中的调试器一样。就是在浏览器中按下 F12出现的那个工具。但是在手机上,你没办法按 F12,而这个 weinre 就是在手机上的 F12,与传统的不同的是,它是在手机上浏览你的 web 页面,在 PC 上查看调试工具,非常方便,这就是所谓的远程。

为什么用 weinre?

现代浏览器中调试工具都非常强大了,可以直接模拟手机设备,为什么还要用 weinre 这么麻烦的东西呢?
我觉得 PC 端的浏览器虽说可以模拟,但模拟毕竟还是模拟,还只是鼠标长按滑来滑去。在开发过程中,使用手机或平板直接来感受是多么的酷,指尖在移动设备的屏幕上摩擦摩擦!给人的直观感受绝对秒杀浏览器的模拟。

原理

使用一种工具之前,了解它的原理和结构是很有帮助的。weinre 作为一种远程调试工具,在结构上分为三层:
  • 目标页面(target):被调试的页面,页面已嵌入 weinre 的远程 js,下文会介绍;
  • Debug客户端(client):本地的 Web Inspector 调试客户端;
  • Debug服务端(agent):一个 HTTP Server,为目标页面与 Debug 客户端建立通信。
三层结构如下图所示:
http-flow
weinre 的 debug 客户端是基于 Web Inspector 开发,而 Web Inspector 只与以 WebKit 为核心的浏览器兼容,所以 Weinre 的客户端只能用 Chrome 或者 Safari 打开。
官网上也有相应的平台支持说明:
  • Platforms supported - debug server 服务端
    任何支持 node.js 的平台。
  • Platforms supported - debug client 客户端(跑 debugger 界面的浏览器)
    • Google Chrome
    • Apple Safari
    • Other recent-ish WebKit-based browsers 其他基于 webkit 内核的现代浏览器
  • Platforms supported - debug target 目标页面(在移动设备中调试运行的目标页面)
    • Android Browser application
    • iOS Mobile Safari application
    • PhoneGap/Cordova
    • other

安装

  1. weinre 是 nodeJS 的一个应用,首先要 安装 nodeJS 运行环境
  2. 使用 npm 命令,安装 weinre
     npm -g install weinre
    
    安装成功后会有类似的信息:
     C:\Users\haoyang\AppData\Roaming\npm\weinre -> C:\Users\haoyang\AppData\Roaming\npm\node_modules\weinre\weinre
     weinre@2.0.0-pre-I0Z7U9OV C:\Users\haoyang\AppData\Roaming\npm\node_modules\weinre
     ├── underscore@1.7.0
     ├── nopt@3.0.2 (abbrev@1.0.7)
     └── express@2.5.11 (mime@1.2.4, qs@0.4.2, mkdirp@0.3.0, connect@1.9.2)
    

使用

  1. 启动服务
     weinre --boundHost -all- --httpPort 8081
    
    • –boundHost [hostname | ip address | -all-]
      The ip address to bind the server to.
    • –httpPort [portNumber]
      The port to run the HTTP server on.
    更多配置项参考 官网的说明
  2. 启动成功后看到如下界面:
    weinre
  3. 给目标页面添加一行脚本
    可以看到 2.中的 Target Script 说要添加一行脚本到要调试的 web 页面中。
    Target Script
    You can use this script to inject the weinre target code into your web page.
    http://localhost:8081/target/target-script-min.js#anonymous
    Example:
     <script src="http://localhost:8081/target/target-script-min.js#anonymous"></script>
    
    这里要说明一下,要把上面的 localhost 换为本机的 ip 地址。
    我们可以在命令行中 使用 ipconfig 得到 ip 地址,如下(当然你的可能和我的不一样):
     IPv4 地址 . . . . . . . . . . . . : 192.168.1.107
    
    即插入如下代码:
     <script src="http://192.168.1.107:8081/target/target-script-min.js#anonymous"></script>
    
  4. 进入调试页面
    PC 端访问这个地址:
    debug client user interface: http://localhost:8081/client/#anonymous
    此时 target 为 none,如下图:
    target-none
    现在我们要用手机访问同一个局域网下的这个目标页面。我们可以把要调试的页面放到这个路径下:
     C:\Users\haoyang\AppData\Roaming\npm\node_modules\weinre\web
    
    通过 http://192.168.1.107:8081/FILE_NAME 在手机上访问,就可以看到了。当然前提是同一个局域网。
    但是这样可能不太灵活,每次都要把目标页面放到指定的目录下。所以我们可以另外开一个服务器。
    我使用了基于 node.js 的 http-server 工具。将要调试的页面发布。这样我就能通过 ip 地址加端口号在手机上访问到了。
    我在手机上访问 http://192.168.1.107:8080 打开要调试的页面,此时 debug client user interface 中自动检测到 target。就可以进行调试了!
    如下图:
    target
    phone

参考

相关帖子:http://briteming.blogspot.com/2016/06/web-app.html

Web App相关技术

往前推2到3年,前端工程师还在忧心忡忡地想,移动互联网时代下,前端是不是没有生存空间了。但今天一看,在我们团队,前端工程师超过一半的工作都是在做移动端的Web或者APP的开发。移动Web或者APP在技术本质上是和做桌面端Web没有本质区别,但是移动端的坑那是非常的多,通过学习这部分内容,让你成为一名桌面移动通吃的前端开发工程师。

概念

上面这个 slide 资料讲的非常好,算是一个入门的介绍吧。带我们建立基本的移动 web 开发知识体系和常见问题的实践。包含以下几个方面:
  • 基本概念
    • Native
      本地应用 使用 Java \ Objective-C \ Swift 开发
    • WebApp
      网页应用 html5 开发
    • Hybrid
      混合应用 ooxx(native, web)
    • 对比
  • 视觉
    • 设备的像素
    • 文字单位使用 rem
    • viewport 属性
    • 横屏竖屏
    • Flex 伸缩布局
    • 响应式设计
    • 软键盘
    • 隐藏地址栏
    • 苹果设备添加到主屏图标
  • 交互
    • Touch
    • click 延迟
    • Scroll
    • Gestures(hammer –A javascript library for multi-touch gestures)
    • 手指友好设计
    • HTML5 APIS(图像,摇动,声音等)
  • 实践
    • 屏蔽点击元素时的阴影
    • 图像(像素、矢量图标、base64 减少请求、lazyload)
    • CSS3(合理使用渐变/圆角/阴影、代替 js 动画、translate3d、解决动画闪烁)
    • localStorage
    • 避免(iframe、fixed + input)
    • SPA 或 Multi page
    • can I use
    • 压缩合并
    • @G/3G 下建立连接时间
  • 调试
    • 浏览器自己的调试工具,模拟手机设备
    • weinre

head 标签

参考:
上面的链接详细的讲解了:
  • DOCTYPE
  • charset
  • lang属性
  • 优先使用 IE 最新版本和 Chrome
  • 360 使用Google Chrome Frame
  • SEO 优化部分:页面标题
  • 为移动设备添加 viewport
    viewport 可以让布局在移动浏览器上显示的更好。 通常会写
<meta name ="viewport" content ="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">
<!-- `width=device-width` 会导致 iPhone 5 添加到主屏后以 WebApp 全屏模式打开页面时出现黑边 http://bigc.at/ios-webapp-viewport-meta.orz -->
  • content 参数:
    • width viewport 宽度(数值/device-width)
    • height viewport 高度(数值/device-height)
    • initial-scale 初始缩放比例
    • maximum-scale 最大缩放比例
    • minimum-scale 最小缩放比例
    • user-scalable 是否允许用户缩放(yes/no)
  • ios 设备,iOS 图标,Android,Windows 8
总结:
<!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 -->
<html lang="zh-cmn-Hans"> <!-- 更加标准的 lang 属性写法 http://zhi.hu/XyIa -->
<head>
    <!-- 声明文档使用的字符编码 -->
    <meta charset='utf-8'>
    <!-- 优先使用 IE 最新版本和 Chrome -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <!-- 页面描述 -->
    <meta name="description" content="不超过150个字符"/>
    <!-- 页面关键词 -->
    <meta name="keywords" content=""/>
    <!-- 网页作者 -->
    <meta name="author" content="name, email@gmail.com"/>
    <!-- 搜索引擎抓取 -->
    <meta name="robots" content="index,follow"/>
    <!-- 为移动设备添加 viewport -->
    <meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no">
    <!-- `width=device-width` 会导致 iPhone 5 添加到主屏后以 WebApp 全屏模式打开页面时出现黑边 http://bigc.at/ios-webapp-viewport-meta.orz -->

    <!-- iOS 设备 begin -->
    <meta name="apple-mobile-web-app-title" content="标题">
    <!-- 添加到主屏后的标题(iOS 6 新增) -->
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <!-- 是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏 -->

    <meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">
    <!-- 添加智能 App 广告条 Smart App Banner(iOS 6+ Safari) -->
    <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
    <!-- 设置苹果工具栏颜色 -->
    <meta name="format-detection" content="telphone=no, email=no"/>
    <!-- 忽略页面中的数字识别为电话,忽略email识别 -->
    <!-- 启用360浏览器的极速模式(webkit) -->
    <meta name="renderer" content="webkit">
    <!-- 避免IE使用兼容模式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 -->
    <meta name="HandheldFriendly" content="true">
    <!-- 微软的老式浏览器 -->
    <meta name="MobileOptimized" content="320">
    <!-- uc强制竖屏 -->
    <meta name="screen-orientation" content="portrait">
    <!-- QQ强制竖屏 -->
    <meta name="x5-orientation" content="portrait">
    <!-- UC强制全屏 -->
    <meta name="full-screen" content="yes">
    <!-- QQ强制全屏 -->
    <meta name="x5-fullscreen" content="true">
    <!-- UC应用模式 -->
    <meta name="browsermode" content="application">
    <!-- QQ应用模式 -->
    <meta name="x5-page-mode" content="app">
    <!-- windows phone 点击无高光 -->
    <meta name="msapplication-tap-highlight" content="no">
    <!-- iOS 图标 begin -->
    <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png"/>
    <!-- iPhone 和 iTouch,默认 57x57 像素,必须有 -->
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/apple-touch-icon-114x114-precomposed.png"/>
    <!-- Retina iPhone 和 Retina iTouch,114x114 像素,可以没有,但推荐有 -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144x144-precomposed.png"/>
    <!-- Retina iPad,144x144 像素,可以没有,但推荐有 -->
    <!-- iOS 图标 end -->

    <!-- iOS 启动画面 begin -->
    <link rel="apple-touch-startup-image" sizes="768x1004" href="/splash-screen-768x1004.png"/>
    <!-- iPad 竖屏 768 x 1004(标准分辨率) -->
    <link rel="apple-touch-startup-image" sizes="1536x2008" href="/splash-screen-1536x2008.png"/>
    <!-- iPad 竖屏 1536x2008(Retina) -->
    <link rel="apple-touch-startup-image" sizes="1024x748" href="/Default-Portrait-1024x748.png"/>
    <!-- iPad 横屏 1024x748(标准分辨率) -->
    <link rel="apple-touch-startup-image" sizes="2048x1496" href="/splash-screen-2048x1496.png"/>
    <!-- iPad 横屏 2048x1496(Retina) -->

    <link rel="apple-touch-startup-image" href="/splash-screen-320x480.png"/>
    <!-- iPhone/iPod Touch 竖屏 320x480 (标准分辨率) -->
    <link rel="apple-touch-startup-image" sizes="640x960" href="/splash-screen-640x960.png"/>
    <!-- iPhone/iPod Touch 竖屏 640x960 (Retina) -->
    <link rel="apple-touch-startup-image" sizes="640x1136" href="/splash-screen-640x1136.png"/>
    <!-- iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina) -->
    <!-- iOS 启动画面 end -->

    <!-- iOS 设备 end -->
    <meta name="msapplication-TileColor" content="#000"/>
    <!-- Windows 8 磁贴颜色 -->
    <meta name="msapplication-TileImage" content="icon.png"/>
    <!-- Windows 8 磁贴图标 -->

    <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/>
    <!-- 添加 RSS 订阅 -->
    <link rel="shortcut icon" type="image/ico" href="/favicon.ico"/>
    <!-- 添加 favicon icon -->

    <title>标题</title>
</head>
<body>
</body>
</html>

页面切换动画

关于 HammerJS 的一个中文文档

CSS Processing

CSS语言由于其自身语言设计的问题,加上一些浏览器兼容性问题,往往会使得我们在写它的时候,要写很多冗余代码,或者为了兼容性对同一个样式设定写好几遍。针对这些问题,诞生了CSS预处理和后处理的概念及相关方法、工具。
这些工具和方法帮助我们能够更加高效地书写可维护性更强的CSS代码。
这里我尝试使用了 Sass,果然很好用。下面记录几个 sass 教程。

安装

首先要有 ruby 环境。
由于国内网络原因(你懂的),导致 rubygems.org 存放在 Amazon S3 上面的资源文件间歇性连接失败。这时候我们可以通过gem sources命令来配置源,先移除默认的 https://rubygems.org 源,然后添加淘宝的源 https://ruby.taobao.org/,然后查看下当前使用的源是哪个,如果是淘宝的,则表示可以输入 sass 安装命令 gem install sass 了。
$ gem sources --remove https://rubygems.org/
$ gem sources -a https://ruby.taobao.org/
$ gem sources -l
*** CURRENT SOURCES ***

https://ruby.taobao.org
# 请确保只有 ruby.taobao.org
$ gem install sass

编译

sass --watch style.scss:style.css --style expanded

补充

rem
字体单位使用 rem,用户在手机上设置了字体大小时,不会打破布局,造成混乱。

安全

安全是大家经常容易忽视,但其实一旦出现影响会非常大的问题,尤其对于没有经历过企业开发,或者没有踩过坑的同学,如果等到公司工作,做实际项目后非常容易发生安全问题。

分类

WEB基本攻击大致可以分为三大类:“资源枚举”、“参数操纵” 和 “其它攻击”
  • 资源枚举
  • 参数操纵
    • SQL注入
    • XPath注入
    • cgi命令执行
    • XXS(cross-site scripting跨域脚本攻击)其重点是“跨域”和“客户端执行”
      • Reflected XSS ——基于反射的XSS攻击。主要依靠站点服务端返回脚本,在客户端触发执行从而发起WEB攻击。
      • DOM-based or local XSS——基于DOM或本地的XSS攻击
      • Stored XSS——基于存储的XSS攻击
    • 会话劫持
  • 其它攻击
    • CSRF(cross-site request forgery)跨站请求伪造
    • 钓鱼攻击指的是网站的伪造,比如ta0bao.com,然后在其中应用XSS等方式发起攻击。
    • 拒绝服务(DoS)指的是向网站发起洪水一样的请求(Traffic Floor),导致服务器超负荷并关闭,处理方法常规是采用QoS(Quality of Service)的软硬件解决方案。

关于 XSS

跨网站脚本(Cross-site scripting,通常简称为XSS或跨站脚本或跨站脚本攻击)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。
XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java, VBScript, ActiveX, Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
——维基百科

XSS 防护

  1. 浏览器解析顺序:
    HTML Parser » CSS Parser » JavaScript Parser
  2. 浏览器解码顺序:
    HTML Decoding » URL Decoding » JavaScript Decoding
  3. 具体的防护方式:
    • 验证输入并且基于语境和按照正确的顺序转义不可信数据
      • HTML 中的字符串
      • HTML 属性中的字符串
      • 事件句柄属性和 JavaScript 中的字符串
      • HTML 属性中的 URL 路径
      • HTML 风格属性和 CSS 中的字符串
      • JavaScript 中的 HTML
    • 始终遵循白名单优于黑名单的做法
    • 使用 UTF-8 为默认的字符编码以及设置 content 为 text/html
    • 不要将用户可以控制的文本放在标签前。通过使用不同的字符集注射可以导致 XSS。
    • 使用 <!DOCTYPE html>
    • 使用推荐的 HTTP 响应头进行 XSS 防护
    • 防止 CRLF 注入/HTTP 响应拆分
    • 禁止 TRACE 和其他非必要方法
对于 innerHTML 的方式输出的,我们可以采用如下的方式转码
/**
 * 转码 XSS 防护
 * @param  {String} str 用户输入的字符串
 * @return {String}     转码后的字符串
 */
function changeCode(str) {
    str = str.replace(/&/g, "&amp;")
              .replace(/</g, "&lt;")
              .replace(/>/g, "&gt;")
              .replace(/"/g, "&quot;")
              .replace(/'/g, "&#x27;")
              .replace(/\//g, "&#x2f;");
    return str;
}

参考:

性能优化

在自己做一些小项目时,可能是学校的一些网站项目,流量可能日均都不超过500,而且大多是校园局域网内访问;或者是开发一些实验室的MIS系统,这辈子你都不会去使用你开发的这个系统。在这样一些项目中,性能优化往往会被你忽略。
但是如果你是做一个日均PV数万、数十万、甚至更大的量级,开发的页面会被全国各地,不同网络条件的用户来进行访问。这个时候,性能问题就无法忽视了。在当今的网络条件下,如果你的页面3秒都无法完成首屏渲染,一定会让你的网站流失很多用户。
整个网站的性能优化有很多的环节和工作,大多数时候,不是前端工程师单独就能完成的,尤其在职能划分明确的公司中,往往需要前后端、运维、DBA等多个职位协同完成。所以,在我们的课程中,主要让你了解整个性能优化都涉及哪些方面的工作,同时,我们会专注介绍一些在前端领域可以重点关注的技术点。
这里就是网页的打开速度,如果你的网页打开速度很慢,那么一定会有用户的流失。所以性能优化很重要。
  • 网页内容
    • 减少http请求次数
    • 减少DNS查询次数
    • 避免页面跳转
    • 缓存Ajax
    • 延迟加载
    • 提前加载
    • 减少DOM元素数量
    • 根据域名划分内容
    • 减少iframe数量
    • 避免404
  • 服务器
    • 使用CDN
    • 添加Expires 或Cache-Control报文头
    • Gzip压缩传输文件
    • 配置ETags
    • 尽早flush输出
    • 使用GET Ajax请求
    • 避免空的图片src
  • Cookie
    • 减少Cookie大小
    • 页面内容使用无cookie域名
  • CSS
    • 将样式表置顶
    • 避免CSS表达式
    • 用<link>代替@import
    • 避免使用Filters
  • Javascript
    • 将脚本置底
    • 使用外部Javascirpt和CSS文件
    • 精简Javascript和CSS
    • 去除重复脚本
    • 减少DOM访问
    • 使用智能事件处理
  • 图片
    • 优化图像
    • 优化CSS Sprite
    • 不要在HTML中缩放图片
    • 使用小且可缓存的favicon.ico
  • 移动客户端
    • 保持单个内容小于25KB
    • 打包组建成符合文档
具体细节参考文章:
我在 ToDo 这个任务中主要使用了 CDN 来加载静态资源。比如我使用了 百度静态资源公共库。引用了里面的 fontawesome,速度果然比在 GitHub 仓库里快很多。下一步是压缩我自己写的静态资源。
其他参考资料:

模块化

对于一个复杂项目,特别是多人协作的复杂项目,如何合理划分模块,如何更加方便地进行模块加载,如何管理模块之间的依赖,是一个项目团队都会面临的问题,目前业界已经有了一些较为普遍的解决方案,如AMD。这个部分希望你能够通过学习JavaScript的模块化,学习如何合理地规划项目模块,合理使用模块化工具来优化你的项目代码结构。
一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。模块开发需要遵循一定的规范,否则就都乱套了。
根据AMD规范,我们可以使用 define 定义模块,使用 require 调用模块。
目前,通行的 js 模块规范主要有两种:CommonJS 和 AMD

AMD规范

AMD 即 Asynchronous Module Definition,中文名是“异步模块定义”的意思。它是一个在浏览器端模块化开发的规范,服务器端的规范是 CommonJS
模块将被异步加载,模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。
AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出。
详细 API 如下:

CommonJS规范

CommonJS 是服务器端模块的规范,Node.js 采用了这个规范。Node.JS 首先采用了 js 模块化的概念。
根据 CommonJS 规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非定义为 global 对象的属性。
输出模块变量的最好方法是使用 module.exports 对象。

为什么要用 requireJS

试想一下,如果一个网页有很多的js文件,那么浏览器在下载该页面的时候会先加载js文件,从而停止了网页的渲染,如果文件越多,浏览器可能失去响应。其次,要保证js文件的依赖性,依赖性最大的模块(文件)要放在最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。
RequireJS就是为了解决这两个问题而诞生的:
(1)实现js文件的异步加载,避免网页失去响应; (2)管理模块之间的依赖性,便于代码的编写和维护。

requireJS


AMD和CMD

CMD(Common Module Definition) 通用模块定义。该规范明确了模块的基本书写格式和基本交互规则。该规范是在国内发展出来的。AMD是依赖关系前置,CMD是按需加载。
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。 CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。
AMD:提前执行(异步加载:依赖先执行)+延迟执行 CMD:延迟执行(运行到需加载,根据顺序执行)

参考


前端工程化

业界目前有非常多的前端开发工具,完成一些开发过程中可以自动化完成的工作,提高研发效率,并且可以提高多人协作时的开发过程一致性,提高整个项目的运维效率。
在EFE日常工作中,我们是基于EDP,完成项目开发过程中的项目构建、包管理、调试、单测、静态检测、打包、压缩、优化、项目部署等一系列所有工作。
注:
如果网络不好,可以使用 淘宝 NPM 镜像

参考


最终作品

在任务三中,做了一个 PC 端的 ToDo 应用。任务四是将它优化,以适应移动端设备。

ToDo WebApp Version

Details

  • 数据存储
    以 JSON 模拟数据表的形式存储于 LocalStorage 中
       使用数据库的思想,构建3张表。
       cateJson 分类
       childCateJson 子分类
       taskJson 任务
    
       分类表 cate
       ----------------------
       id* | name | child(FK)
       ----------------------
    
       子分类表 childCate
       --------------------------------
       id* | pid(FK) | name | child(FK)
       --------------------------------
    
       任务表 task
       ----------------------------------------------
       id* | pid(FK) | finish | name | date | content
       ----------------------------------------------
    
  • 使用 Sass 重构了 CSS 代码
    使用分块、继承等方式,使得代码更加清晰明了。
  • 响应式布局
    针对手机端细节做了很多调整,更符合手机上的视觉交互习惯。
  • 加入页面切换效果
    使用 translate3d(),纯 CSS3 切换动画效果。
  • 处理了 XSS 防护
    对可能造成破坏的字符进行转码。
  • 性能优化
    使用 CDN 处理静态资源 fontAwesome,压缩静态资源等
  • 模块化
    使用 requireJS 模块化 JavaScript 代码。重构 JavaScript 代码。优化之前写的耦合性高的绑定事件,重新绑定事件,降低耦合性。期间根据具体需求重写了事件代理的代码。
  • 前端工程化
    使用 gulp,自动编译 Sass,压缩 CSS 和 JavaScript 代码。并且配置了自动流程。

其他

-webkit-tap-highlight-color 属性

感谢 fiona 指出。
safari移动端点击的时候会闪一下加上 -webkit-tap-highlight-color: transparent; 就不会闪了。
参考:

textarea 标签 disabled 颜色

  • 为什么用 disabled 属性?
    因为我发现仅仅使用 readonly 属性,在 IE 下是显示光标的。于是使用 disabled。
  • 出现的问题
    各家浏览器对于 disabled 属性有自己的样式设定,比如 IE 下是灰色的。苹果设备下也是。改变这些样式的方法也不是统一的。如果要兼容 Safari 必须加上
background: #fff;
-webkit-text-fill-color: rgba(0, 0, 0, 1);
-webkit-opacity: 1;
于是最终代码如下:
textarea:disabled {
    color:#000;
    background: #fff;
    -webkit-text-fill-color: rgba(0, 0, 0, 1);
    -webkit-opacity: 1;
}