浏览器兼容-浏览器兼容性待整理(一)

常见浏览器兼容性问题与解决方案

  所谓的浏览器兼容性问题,是指因为不同的浏览器对同一段代码有不同的解析,造成页面显示效果不统一的情况。在大多数情况下,我们的需求是,无论用户用什么浏览器来查看我们的网站或者登陆我们的系统,都应该是统一的显示效果。所以浏览器的兼容性问题是前端开发人员经常会碰到和必须要解决的问题。

  在学习浏览器兼容性之前,我想把前端开发人员划分为两类:

  第一类是精确按照设计图开发的前端开发人员,可以说是精确到1px的,他们很容易就会发现设计图的不足,并且在很少的情况下会碰到浏览器的兼容性问题,而这些问题往往都死浏览器的bug,并且他们制作的页面后期易维护,代码重用问题少,可以说是比较牢固放心的代码。

  第二类是基本按照设计图来开发的前端开发人员,很多细枝末节差距很大,不如间距,行高,图片位置等等经常会差几px。某种效果的实现也是反复调试得到,具体为什么出现这种效果还模模糊糊,整体布局十分脆弱。稍有改动就乱七八糟。代码为什么这么写还不知所以然。这类开发人员往往经常为兼容性问题所困。修改好了这个浏览器又乱了另一个浏览器。改来改去也毫无头绪。其实他们碰到的兼容性问题大部分不应该归咎于浏览器,而是他们的技术本身了。

  文章主要针对的是第一类,严谨型的开发人员,因此这里主要从浏览器解析差异的角度来分析兼容性问题。

  浏览器兼容问题一:不同浏览器的标签默认的外补丁和内补丁不同
W.SVP.ZU%9

  问题症状:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大。

  碰到频率:100%

  解决方案:CSS里    *

  备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符*来设置各个标签的内外补丁是0。

  浏览器兼容问题二:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大

  问题症状:常见症状是IE6中后面的一块被顶到下一行

  碰到频率:90%(稍微复杂点的页面都会碰到,float布局最常见的浏览器兼容问题)

  解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性

  备注:我们最常用的就是div+CSS布局了,而div就是一个典型的块属性标签,横向布局的时候我们通常都是用div float实现的,横向的间距设置如果用margin实现,这就是一个必然会碰到的兼容性问题。

  浏览器兼容问题三:设置较小高度标签(一般小于10px),在IE6,IE7,遨游中高度超出自己设置高度

  问题症状:IE6、7和遨游里这个标签的高度不受控制,超出自己设置的高度

  碰到频率:60%

  解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。

  备注:这种情况一般出现在我们设置小圆角背景的标签里。出现这个问题的原因是IE8之前的浏览器都会给标签一个最小默认的行高的高度。即使你的标签是空的,这个标签的高度还是会达到默认的行高。

  浏览器兼容问题四:行内属性标签,设置display:block后采用float布局,又有横行的margin的情况,IE6间距bug

  问题症状:IE6里的间距比超过设置的间距

  碰到几率:20%

  解决方案:在display:block;后面加入display:inline;display:table;

  备注:行内属性标签,为了设置宽高,我们需要设置display:block;(除了input标签比较特殊)。在用float布局并有横向的margin后,在IE6下,他就具有了块属性float后的横向margin的bug。不过因为它本身就是行内属性标签,所以我们再加上display:inline的话,它的高宽就不可设了。这时候我们还需要在display:inline后面加入display:talbe。

  浏览器兼容问题五:图片默认有间距

  问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,加了问题一中提到的通配符也不起作用。

  碰到几率:20%

  解决方案:使用float属性为img布局

  备注:因为img标签是行内属性标签,所以只要不超出容器宽度,img标签都会排在一行里,但是部分浏览器的img标签之间会有个间距。去掉这个间距使用float是正道。(我的一个学生使用负margin,虽然能解决,但负margin本身就是容易引起浏览器兼容问题的用法,所以我禁止他们使用)

  浏览器兼容问题六:标签最低高度设置min-height不兼容

  问题症状:因为min-height本身就是一个不兼容的CSS属性,所以设置min-height时不能很好的被各个浏览器兼容

  碰到几率:5%

  解决方案:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !ImportAnt; height:200px; overflow:visible;}

  备注:在B/S系统前端开时,有很多情况下我们又这种需求。当内容小于一个值(如300px)时。容器的高度为300px;当内容高度大于这个值时,容器高度被撑高,而不是出现滚动条。这时候我们就会面临这个兼容性问题。

  浏览器兼容问题七:透明度的兼容CSS设置

  做兼容页面的方法是:每写一小段代码(布局中的一行或者一块)我们都要在不同的浏览器中看是否兼容,当然熟练到一定的程度就没这么麻烦了。建议经常会碰到兼容性问题的新手使用。很多兼容性问题都是因为浏览器对标签的默认属性解析不同造成的,只要我们稍加设置都能轻松地解决这些兼容问题。如果我们熟悉标签的默认属性的话,就能很好的理解为什么会出现兼容问题以及怎么去解决这些兼容问题。

1.     /* CSS hack*/

我很少使用hacker的,可能是个人习惯吧,我不喜欢写的代码IE不兼容,然后用hack来解决。不过hacker还是非常好用的。使用hacker我可以把浏览器分为3类:IE6 ;IE7和遨游;其他(IE8 Chrome ff Safari opera等)

  ◆IE6认识的hacker 是下划线_ 和星号 *

  ◆IE7 遨游认识的hacker是星号 *

  比如这样一个CSS设置:

1.     height:300px;*height:200px;_height:100px;

  IE6浏览器在读到height:300px的时候会认为高时300px;继往下读,他也认识*heihgt, 所以当IE6读到*height:200px的时候会覆盖掉前一条的相冲突设置,认为高度是200px。继续往下读,IE6还认识_height,所以他又会覆盖掉200px高的设置,把高度设置为100px;

IE7和遨游也是一样的从高度300px的设置往下读。当它们读到*height200px的时候就停下了,因为它们不认识_height。所以它们会把高度解析为200px,剩下的浏览器只认识第一个height:300px;所以他们会把高度解析为300px。因为优先级相同且想冲突的属性设置后一个会覆盖掉前一个,所以书写的次序是很重要的。

在网站设计的时候,应该注意css样式兼容不同浏览器问题,特别是对完全使用DIV CSS设计的网,就应该更注意IE6 IE7 FF对CSS样式的兼容,不然,你的网乱可能出去不想出现的效果!

所有浏览器 通用
height: 100px;

IE6 专用
_height: 100px;

IE6 专用
*height: 100px;

IE7 专用
*+height: 100px;

IE7、FF 共用
height: 100px !important;

一、CSS 兼容
以下两种方法几乎能解决现今所有兼容.

1, !important (不是很推荐,用下面的一种感觉最安全)

随着IE7对!important的支持, !important 方法现在只针对IE6的兼容.(注意写法.记得该声明位置需要提前.)

代码:
<style>
#wrapper {
width: 100px!important; /* IE7+FF */
width: 80px; /* IE6 */
}
</style>

2, IE6/IE77对FireFox <from 针对firefoxie6 ie7的css样式>

*+html 与 *html 是IE特有的标签, firefox 暂不支持.而*+html又为 IE7特有标签.

代码:
<style>
#wrapper { width: 120px; } /* FireFox */
*html #wrapper { width: 80px;} /* ie6 fixed */
*+html #wrapper { width: 60px;} /* ie7 fixed, 注意顺序 */
</style>

注意:
*+html 对IE7的兼容 必须保证HTML顶部有如下声明:

代码:
<!DOCTYPE HTML PUBLIC “-//W3C//DTDHTML 4.01 Transitional//EN” ”http://www.w3.org/TR/html4/loose.dtd”>

二、万能 float 闭合(非常重要!) 可以用这个解决多个div对齐时的间距不对,

关于 clear float 的原理可参见 [How ToClear Floats Without Structural Markup]
将以下代码加入Global CSS 中,给需要闭合的div加上 class=”clearfix” 即可,屡试不爽.

代码:
<style>
/* Clear Fix */
.clearfix:after {
content:”.”;
display:block;
height:0;
clear:both;
visibility:hidden;
}
.clearfix {
display:inline-block;
}
/* Hide from IE Mac \*/
.clearfix {display:block;}
/* End hide from IE Mac */
/* end of clearfix */
</style>

***********************************************************************************************************************

三、其他兼容技巧(相当有用)

1, FF下给 div 设置 padding 后会导致 width 和 height 增加, 但IE不会.(可用!important解决)
2, 居中问题.
1).垂直居中.将 line-height 设置为当前 div 相同的高度, 再通过 vetical-align: middle.( 注意内容不要换行.)
2).水平居中. margin: 0 auto;(当然不是万能)
3, 若需给 a 标签内内容加上 样式, 需要设置 display: block;(常见于导航标签)
4, FF 和 IE 对 BOX 理解的差异导致相差 2px 的还有设为 float的div在ie下 margin加倍等问题.
5, ul 标签在 FF 下面默认有 list-style 和 padding . 最好事先声明, 以避免不必要的麻烦. (常见于导航标签和内容列表)
6, 作为外部 wrapper 的 div 不要定死高度, 最好还加上 overflow: hidden.以达到高度自适应.
7, 关于手形光标. cursor: pointer. 而hand只适用于 IE.贴上代码:

兼容代码:兼容最推荐的模式。
/* FF */
.submitbutton {
float:left;
width: 40px;
height: 57px;
margin-top: 24px;
margin-right: 12px;
}
/* IE6 */
*html .submitbutton {
margin-top: 21px;
}
/* IE7 */
*+html .submitbutton {
margin-top: 21px;
}

来自:还有 很多 没有摘录 ,留待后面摘录。
https://blog.csdn.net/weixin_38536027/article/details/79375411

浏览器兼容-浏览器兼容性待整理(二)

浏览器兼容性问题解决方案 · 总结

普及:浏览器的兼容性问题,往往是个别浏览器(没错,就是那个与众不同的浏览器)对于一些标准的定义不一致导致的。俗话说:没有IE就没有伤害。

贴士:内容都是自己总结的,不免会出现错误或者bug,欢迎更正和补充,本帖也会不断更新。

Normalize.css

不同浏览器的默认样式存在差异,可以使用 Normalize.css 抹平这些差异。当然,你也可以定制属于自己业务的 reset.css

<link href="https://cdn.bootcss.com/normalize/7.0.0/normalize.min.css" rel="stylesheet">

简单粗暴法

* { margin: 0; padding: 0; }

html5shiv.js

解决 ie9 以下浏览器对 html5 新增标签不识别的问题。

<!--[if lt IE 9]>
  <script type="text/javascript" src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<![endif]-->

respond.js

解决 ie9 以下浏览器不支持 CSS3 Media Query 的问题。

<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>

picturefill.js

解决 IE 9 10 11 等浏览器不支持 <picture> 标签的问题

<script src="https://cdn.bootcss.com/picturefill/3.0.3/picturefill.min.js"></script>

IE 条件注释

IE 的条件注释仅仅针对IE浏览器,对其他浏览器无效

IE 属性过滤器(较为常用的hack方法)

针对不同的 IE 浏览器,可以使用不同的字符来对特定的版本的 IE 浏览器进行样式控制

image
image
image
image

浏览器 CSS 兼容前缀

-o-transform:rotate(7deg); // Opera

-ms-transform:rotate(7deg); // IE

-moz-transform:rotate(7deg); // Firefox

-webkit-transform:rotate(7deg); // Chrome

transform:rotate(7deg); // 统一标识语句

a 标签的几种 CSS 状态的顺序

很多新人在写 a 标签的样式,会疑惑为什么写的样式没有效果,或者点击超链接后,hoveractive 样式没有效果,其实只是写的样式被覆盖了。

正确的a标签顺序应该是:==love hate==

  • link:平常的状态
  • visited:被访问过之后
  • hover:鼠标放到链接上的时候
  • active:链接被按下的时候

完美解决 Placeholder

<input type="text" value="Name *" onFocus="this.value = '';" onBlur="if (this.value == '') {this.value = 'Name *';}">

清除浮动 最佳实践

.fl { float: left; }
.fr { float: right; }
.clearfix:after { display: block; clear: both; content: ""; visibility: hidden; height: 0; }
.clearfix { zoom: 1; }

BFC 解决边距重叠问题

当相邻元素都设置了 margin 边距时,margin 将取最大值,舍弃小值。为了不让边距重叠,可以给子元素加一个父元素,并设置该父元素为 BFC:overflow: hidden;

<div class="box" id="box">
  <p>Lorem ipsum dolor sit.</p>

  <div style="overflow: hidden;">
    <p>Lorem ipsum dolor sit.</p>
  </div>

  <p>Lorem ipsum dolor sit.</p>
</div>

IE6 双倍边距的问题

设置 ie6 中设置浮动,同时又设置 margin,会出现双倍边距的问题

display: inline;

解决 IE9 以下浏览器不能使用 opacity

opacity: 0.5;
filter: alpha(opacity = 50);
filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50);

解决 IE6 不支持 fixed 绝对定位以及IE6下被绝对定位的元素在滚动的时候会闪动的问题

/* IE6 hack */
*html, *html body {
  background-image: url(about:blank);
  background-attachment: fixed;
}
*html #menu {
  position: absolute;
  top: expression(((e=document.documentElement.scrollTop) ? e : document.body.scrollTop) + 100 + 'px');
}

IE6 背景闪烁的问题

问题:链接、按钮用 CSSsprites 作为背景,在 ie6 下会有背景图闪烁的现象。原因是 IE6没有将背景图缓存,每次触发 hover 的时候都会重新加载

解决:可以用 JavaScript 设置 ie6 缓存这些图片:

document.execCommand("BackgroundImageCache", false, true);

解决在 IE6 下,列表与日期错位的问题

日期<span> 标签放在标题 <a> 标签之前即可

解决 IE6 不支持 min-height 属性的问题

min-height: 350px;
_height: 350px;

让 IE7 IE8 支持 CSS3 background-size属性

由于 background-size 是 CSS3 新增的属性,所以 IE 低版本自然就不支持了,但是老外写了一个 htc 文件,名叫 background-size polyfill,使用该文件能够让 IE7、IE8 支持 background-size 属性。其原理是创建一个 img 元素插入到容器中,并重新计算宽度、高度、left、top 等值,模拟 background-size 的效果。

html {
  height: 100%;
}
body {
  height: 100%;
  margin: 0;
  padding: 0;
  background-image: url('img/37.png');
  background-repeat: no-repeat;
  background-size: cover;
  -ms-behavior: url('css/backgroundsize.min.htc');
  behavior: url('css/backgroundsize.min.htc');
}

IE6-7 line-height 失效的问题

问题:在ie 中 img 与文字放一起时,line-height 不起作用

解决:都设置成 float

width:100%

width:100% 这个东西在 ie 里用很方便,会向上逐层搜索 width 值,忽视浮动层的影响.

Firefox 下搜索至浮动层结束,如此,只能给中间的所有浮动层加 width:100%才行,累啊。

opera 这点倒学乖了,跟了 ie

cursor:hand

显示手型 cursor: hand,ie6/7/8、opera 都支持,但是safari 、 ff 不支持

cursor: pointer;

td 自动换行的问题

问题:table 宽度固定,td 自动换行

解决:设置 Table 为 table-layout: fixedtd 为 word-wrap: break-word

让层显示在 FLASH 之上

想让层的内容显示在 flash 上,把 FLASH 设置透明即可

1、<param name=" wmode " value="transparent" />
2、<param name="wmode" value="opaque"/>

键盘事件 keyCode 兼容性写法

var inp = document.getElementById('inp')
var result = document.getElementById('result')

function getKeyCode(e) {
  e = e ? e : (window.event ? window.event : "")
  return e.keyCode ? e.keyCode : e.which
}

inp.onkeypress = function(e) {
  result.innerHTML = getKeyCode(e)
}

求窗口大小的兼容写法

// 浏览器窗口可视区域大小(不包括工具栏和滚动条等边线)
// 1600 * 525
var client_w = document.documentElement.clientWidth || document.body.clientWidth;
var client_h = document.documentElement.clientHeight || document.body.clientHeight;

// 网页内容实际宽高(包括工具栏和滚动条等边线)
// 1600 * 8
var scroll_w = document.documentElement.scrollWidth || document.body.scrollWidth;
var scroll_h = document.documentElement.scrollHeight || document.body.scrollHeight;

// 网页内容实际宽高 (不包括工具栏和滚动条等边线)
// 1600 * 8
var offset_w = document.documentElement.offsetWidth || document.body.offsetWidth;
var offset_h = document.documentElement.offsetHeight || document.body.offsetHeight;

// 滚动的高度
var scroll_Top = document.documentElement.scrollTop||document.body.scrollTop;

DOM 事件处理程序的兼容写法(能力检测)

var eventshiv = {
    // event兼容
    getEvent: function(event) {
        return event ? event : window.event;
    },

    // type兼容
    getType: function(event) {
        return event.type;
    },

    // target兼容
    getTarget: function(event) {
        return event.target ? event.target : event.srcelem;
    },

    // 添加事件句柄
    addHandler: function(elem, type, listener) {
        if (elem.addEventListener) {
            elem.addEventListener(type, listener, false);
        } else if (elem.attachEvent) {
            elem.attachEvent('on' + type, listener);
        } else {
            // 在这里由于.与'on'字符串不能链接,只能用 []
            elem['on' + type] = listener;
        }
    },

    // 移除事件句柄
    removeHandler: function(elem, type, listener) {
        if (elem.removeEventListener) {
            elem.removeEventListener(type, listener, false);
        } else if (elem.detachEvent) {
            elem.detachEvent('on' + type, listener);
        } else {
            elem['on' + type] = null;
        }
    },

    // 添加事件代理
    addAgent: function (elem, type, agent, listener) {
        elem.addEventListener(type, function (e) {
            if (e.target.matches(agent)) {
                listener.call(e.target, e); // this 指向 e.target
            }
        });
    },

    // 取消默认行为
    preventDefault: function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    // 阻止事件冒泡
    stopPropagation: function(event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    }
};

 

关注下面的标签,发现更多相似文章

链接:https://www.zhihu.com/question/20984284/answer/19069622

web概述-css发展简史

CSS3 标准

早在2001年W3C就完成了CSS3的草案规范。CSS3规范的一个新特点是被分为若干个相互独立的模块。一方面分成若干较小的模块较利于规范及时更新和发布,及时调整模块的内容,这些模块独立实现和发布,也为日后CSS的扩展奠定了基础。另外一方面,由于受支持设备和浏览器厂商的限制,没备或者厂商可以有选择的支持一部分模块,支持CSS3的一个子集,这样有利于CSS3的推广 

W3C 仍然在对 CSS3 规范进行开发。

不过,现代浏览器已经实现了相当多的 CSS3 属性。

以下为截至2017年,CSS3各模块的规范情况:

时间 标题 状态 模块
2007年8月9日
基本盒子模型
工作草案 css3-box 
2011年4月12日
多列布局
候选推荐(有新工作草案) css3-multicol 
2011年6月7日 CSS3颜色模块 推荐(有新候选推荐) css3-color 
2011年9月29日
3级选择器
推荐(有新候选推荐) css3-selectors 
2012年6月19日
媒体查询
推荐 css3-mediaqueries 
2013年3月14日
CSS3分页媒体模块
工作草案 css3-page 
2013年4月4日 CSS3条件规则模块 候选推荐 css3-conditional 
2013年8月1日 CSS3文本修饰模块 候选推荐 css-text-decor-3 
2013年10月3日
CSS3字体模块
候选推荐 css-fonts-3 
2014年3月20日 CSS3命名空间模块 推荐 css-namespaces-3 
2014年5月13日 CSS分页媒体模块生成内容 工作草案 css-gcpm-3 
2014年9月9日 CSS3背景和边框模块 候选推荐(有新候选推荐) css3-background 
2014年10月14日 CSS3超链接显示模块 已废弃 css3-hyperlinks 
2014年10月14日 CSS3 Marquee模块 已废弃 css3-marquee 
2014年2月20日 CSS3语法模块 候选推荐 css-syntax-3 
2015年3月26日 CSS模板布局模块 记录 css-template-3 
2015年7月7日 CSS3基本用户界面模块 候选推荐(有新提议推荐) css-ui-3 
2016年5月19日 CSS3级联和继承 候选推荐 css-cascade-3 
2016年6月2日 CSS3生成内容模块 工作草案 css-content-3 
2016年9月29日 CSS3取值和单位模块 候选推荐 css-values-3 
2017年2月9日 CSS3片段模块 候选推荐 css-break-3 
2017年12月7日 CSS3书写模式 候选推荐 css-writing-modes-3 
2017年12月14日 CSS3计数器风格 候选推荐 css-counter-styles-3 

HTML的诞生于20世纪90年代初,1996年底,CSS第一版诞生,1998年5月,CSS2正式发布,2004年,CSS2.1发布,2002-2010年,陆续发布部分css3新增属性。

CSS1 中定义了网页的基本属性:字体、颜色、基本选择器等。

CSS2中在CSS1的基础上添加了高级功能,浮动和定位、高级选择器等(子选择器、相邻选择器、通用选择器)。

CSS3遵循的是模块化开发。发布时间并不是一个时间点,而是一个时间段。

一、css选择器回顾:

(1)通用选择器:*  选择到所有的元素;
(2)选择子元素:> 选择到元素的直接后代
(3)相邻兄弟选择器:+ 选择到紧随目标元素后的第一个元素
(3)普通兄弟选择器:~ 选择到紧随其后的所有兄弟元素
(4)伪元素选择器:
::first-line 匹配文本块的首行
::first-letter 选择文本块的首字母
(5)伪类选择器:
:before,:after在元素内容前面、后面添加内容(相当于行内元素)

例如:选中ul标签后边的第一个div相邻标签。

ul.list +div.box

二、css3结构选择器:

(1):nth-child 选择指定索引处的子元素
(2)nth-child(n) 父元素下的第n个子元素
(3)nth-child(odd)奇数子元素(同nth-child(2n-1))
(4)nth-child(even)偶数子元素(同nth-child(2n))
(5)nth-child(an+b)公式
(6):nth-last-child(n) 倒数第n个子元素
(7):nth-of-type(n) 父元素下的第n个指定类型的子元素
(7):nth-last-of-type 父元素下的倒数第n个指定类型的子元素
(8):first-child 选择父元素下的第一个子元素
(9):last-child 选择父元素下的最后一个子元素
(10):only-child 选择父元素下唯一的子元素
(11):only-of-type选择父元素下指定类型的唯一子元素
(12):root 选择文档的根目录,返回html</span>

例如:选中ul标签里边的第三个li子元素。

ul li:nth-child(3)

三、css3属性选择器:

(1)E[attr] 属性名,不确定具体属性值
(2)E[attr="value"] 指定属性名,并指定其对应属性值
(3)E[attr ~="value"] 指定属性名,其具有多个属性值空格隔开,并包含  value值
(4)E[attr ^= "value"] 指定属性名,属性值以value开头
(5)E[attr $="value"] 指定属性名,属性值以value结束
(6)E[attr *="value"] 指定了属性名,属性值中包含了value
(7)E[attr |= "value"] 指定属性名,属性值以value-开头

例如:选中所有的class类并且以类型是指定的value的div元素,让他的背景颜色变成红色。

div[class="value"]{background:red}

四、css3伪类选择器:

1、UI伪类选择器:

(1):enabled 选择启用状态元素
(2):disabled 选择禁用状态元素
(3):checked 选择被选中的input元素(单选按钮或复选框)
(4):default 选择默认元素
(5):valid、invalid 根据输入验证选择有效或无效的input元素
(6):in-range、out-of-range 选择指定范围之内或者之外受限的元素
(7):repuired、optional 根据是否允许:required属性选择input元素

例如:有3个input复选框,其中第一个被选中了,它的checked=”checked”,其他两个没有,那么让这个被选中的复选框的宽高都变成50px。

input:checked{width:50px;height:50px}

2、动态伪类选择器:

 (1):link 选择链接元素
 (2):visited 选择用户以访问的元素
 (3):hover 鼠标悬停其上的元素
 (4):ative 鼠标点击时触发的事件
 (5):focus 当前获取焦点的元素

例如:滑过一个div的时候,让它的背景颜色变成红色。

div:hover{background:red}

3、其他伪类选择器:

(1):not(<选择器>) 对括号内选择器的选择取反
(2):lang(<目标语言>) 基于lang全局属性的元素
(3):target url片段标识符指向的元素
(4):empty选择内容为空的元素
(5):selection 鼠标光标选择元素内容

例如:有3个div,前两个都有内容,第三个是空的,什么内容都没有,那么让这个空的div的背景颜色变成橙色。

div:empty{background:orange}

总结:这些属性必须得自己一个一个的练习,慢慢才能熟练的掌握!

web概述-web开发技术发展简史

Web的诞生

提到Web,不得不提一个词就是“互联网”。Web是World Wide Web的简称,中文译为万维网。“万维网”和我们经常说的“互联网”是两个联系极其紧密但却不尽相同的概念。今天“互联网”三个字已经承载了太多的内涵,提到互联网,我们通常想到的一种战略思维,或者是一种颠覆传统的商业模式。抛开那些纷繁凌乱的商业化概念,回归技术本身,互联网就是指通过TCP/IP协议族互相连接在一起的计算机网络。而Web是运行在互联网上的一个超大规模的分布式系统。Web设计初衷是一个静态信息资源发布媒介,通过超文本标记语言(HTML)描述信息资源,通过统一资源标识符(URI)定位信息资源,通过超文本转移协议(HTTP)请求信息资源。HTML、URL和HTTP三个规范构成了Web的核心体系结构,是支撑着Web运行的基石。用通俗的一点的话来说,客户端(一般为浏览器)通过URL找到网站(如www.google.com),发出HTTP请求,服务器收到请求后返回HTML页面。可见,Web是基于TCP/IP协议的,TCP/IP协议把计算机连接在一起,而Web在这个协议族之上,进一步将计算机的信息资源连接在一起,形成我们说的万维网。大家开发的Web应用本质上就是可以提供信息或者功能的Web资源,成为Web这个全球超大规模分布式系统中的一部分。在技术层面进一步理解Web和互联网,建议找一本计算机网络的书去看看,了解一下计算机网络的分层结构和发展历史。

1991年8月6日,Tim Berners Lee在alt.hypertext新闻组贴出了一份关于World Wide Web的简单摘要,标志了Web页面在Internet上的首次登场。最早Web主要被一帮科学家们用来共享和传递信息,全世界的Web服务器也就几十台。第一个Web浏览器是Berners Lee在NeXT机器上实现,也只能跑在NeXT机器上,苹果和乔布斯的粉丝对NeXT的历史肯定耳熟能详。真正使得Web开始流行起来的是Mosaic浏览器,这便是曾经大名鼎鼎的Netscape Navigator的前身。Berners Lee在1993年建立了万维网联盟(World Wide Web Consortium,W3C),负责Web相关标准的制定。浏览器的普及和W3C的推动,使得Web上可以访问的资源逐渐丰富起来。这个时候Web的主要功能就是浏览器向服务器请求静态HTML信息。95年的时候马云在美国看到了互联网,更准确的说他其实看到的就是Web,阿里早先做的黄页也就是把企业信息通过进行HTML展示的Web应用。

动态内容的出现:CGI

最初在浏览器中主要展现的是静态的文本或图像信息,GIF图片则第一次为HTML页面引入了动态元素。不过人们已经不仅仅满足于访问放在Web服务器上的静态文件,1993年CGI(Common Gateway Interface)出现了,Web上的动态信息服务开始蓬勃兴起。CGI定义了Web服务器与外部应用程序之间的通信接口标准,因此Web服务器可以通过CGI执行外部程序,让外部程序根据Web请求内容生成动态的内容。Perl因为跨操作系统和易于修改的特性成为CGI的主要编写语言。当然,CGI可以用任何支持标准输入输出和环境变量的语言编写,比如Shell脚本,C/C++语言,只要符合接口标准即可。比如你用C语言编写CGI程序,你把希望返回的HTML内容通过printf输出就可以发送给Web服务器,进而返回给用户。

Web编程脚本语言:PHP/ASP/JSP

这个时候我们已经可以在Web上提供动态功能了,比如网站访问的计数,表单的处理。CGI对每个请求都会启动一个进程来处理,因此性能上的扩展性不高。另外,想象一下用在Perl和C语言中的程序中去输出一大堆复杂的HTML字符串,是不是有点蛋疼,可读性和维护性是个大问题。为了处理更复杂的应用,一种方法是把HTML返回中固定的部分存起来(我们称之为模版),把动态的部分标记出来,Web请求处理的时候,你的程序先生成那部分动态的内容,再把模版读入进来,把动态内容填充进去,形成最终返回。举个例子,搜索一个关键词,搜索引擎的Web服务器可以先从后台索引服务器里拿到数据,然后把这些数据填充到返回结果的HTML模版中,返回给浏览器。但是这件事情自己来做显然太繁琐而且是重复劳动。于是1994年的时候,PHP诞生了,PHP可以把程序(动态内容)嵌入到HTML(模版)中去执行,不仅能更好的组织Web应用的内容,而且执行效率比CGI还更高。之后96年出现的ASP和98年出现的JSP本质上也都可以看成是一种支持某种脚本语言编程(分别是VB和Java)的模版引擎。96年W3C发布了CSS1.0规范。CSS允许开发者用外联的样式表来取代难以维护的内嵌样式,而不需要逐个去修改HTML元素,这让HTML页面更加容易创建和维护。此时,有了这些脚本语言,搭配上后端的数据库技术,Web更是开始大杀四方了,像电子商务这样的应用系统也可以通过Web技术来构建。Web已经从一个静态资源分享媒介真正变为了一个分布式的计算平台了。反过来看,你也应该知道,不是只有当今这些流行脚本语言可以写Web应用,C语言一样可以做这件事情。前面举的搜索引擎通过C语言来获取数据和渲染Web页面的例子在追求极致访问速度的互联网公司是非常常见的,但是脚本语言在开发效率上更胜一筹。

分布式企业计算平台:J2EE/.Net

Web开始广泛用于构建大型应用时,在分布式、安全性、事务性等方面的要求催生了J2EE(现在已更名为Java EE)平台在1999年的诞生,从那时开始为企业应用提供支撑平台的各种应用服务器也开始大行其道。Java Servlet、Java Server Pages (JSP)和Enterprise Java Bean (EJB )是Java EE中的核心规范,Servlet和JSP是运行在服务器端的Web组件,EJB运行在服务器端的业务组件,是一种分布式组件技术。2000年随之而来的.net平台,其ASP.net构件化的Web开发方式以及Visual Stidio.net开发环境的强大支持,大大降低了开发企业应用的复杂度。ASP.Net第一次让程序员可以像拖拽组件来创建Windows Form程序那样来组件化地创建Web页面,Java平台后来出现的JSF也承袭了这一思想。两大平台在相互竞争和模仿中不断向前发展。

框架横飞的年代:MVC,ORM

两大平台诞生之后,组件化编程技术盛极一时,Web技术的发展开始了一段框架横飞的年代,各种辅助Web开发的技术框架层出不穷。虽然脚本语言大大提高了应用开发效率,但是试想一个复杂的大型Web应用,访问各种功能的URL地址纷繁复杂,涉及到的Web页面多种多样,同时还管理着大量的后台数据,因此我们需要在架构层面上解决维护性和扩展性等问题。这个时候,MVC的概念被引入到Web开发中来了。2004年出现的Struts就是当时非常流行的Java Web开发的MVC框架。MVC早在1978年就作为Smalltalk的一种设计模式被提出来了,应用到Web应用上,模型Model用于封装与业务逻辑相关的数据和数据处理方法,视图View是数据的HTML展现,控制器Controller负责响应请求,协调Model和View。Model,View和Controller的分开,是一种典型的关注点分离的思想,不仅使得代码复用性和组织性更好,使得Web应用的配置性和灵活性更好。这是Spring MVC的示意图,典型的MVC架构。

Spring-MVC

此外,数据访问也逐渐通过面向对象的方式来替代直接的SQL访问,出现了ORM(Object Relation Mapping)的概念,2001年出现的Hibernate就是其中的佼佼者,已经成为Java持久层的规范JPA的主要参考和实现。更多的全栈框架开始出现,比如2003年出现的Java开发框架Spring,同时更多的动态语言也被加入到Web编程语言的阵营中,2004年出现的Ruby开发框架Rails,2005出现的Python开发框架Django,都提供了全栈开发框架,或者自身提供Web开发的各种组件,或者可以方便的集成各种组件。比如Spring基于IoC和AOP思想可以方便得整合出全套Web开发组件,SSH(Struts+Spring+Hibernate)一度成为Java Web开发的标配。值得一提的时Rails这个MVC框架,26岁的丹麦大神David Heinemeier Hansson在开发著名项目管理软件BaseCamp的过程中形成,Ruby语言本身在快速开发上的优势,加上Rails诸如崇尚DRY(Don’t)Repeat Yourself)原则, 约定优于配置,拥抱REST等特性,使其迅速成为一个极其流行的Web开发框架。

回归Web本质:REST

注意,看到这里的时候,你会发现Web开发的重点已经不在于HTTP/HTML/URL这样的Web基础架构了,而是各种平台下的各种框架和组件技术(MVC/ORM/分布式组件技术等等)。所以今天很多人可能会用一个MVC框架构建Web网站,但是可能并不了解Web本身。2000年的时候,Roy Fielding在他的博士论文中从构架风格的角度来剖析了Web本身,将Web内在的设计原则和思路系统得论述出来。Roy Fielding是HTTP协议的主要设计者,也是Apache服务器项目的联合创始人,他的这篇博士论文提出来的REST(Representation State Transformation)也成为一种流行的Web架构风格。REST鼓励基于URL来组织系统功能,充分利用HTTP本身的语义,而不是仅仅将HTTP作为一种远程数据传输协议。Web应用的开发应该回归Web的本质特征。Rails在发展过程中也完全拥抱REST,成为REST的坚定支持者。有些人认为REST和MVC是两种对立的风格,其实不尽然,两者是互为补充的,从Rails是一个全面支持REST的MVC框架这一点就可窥见。

浏览器端的魔术:AJAX

Web应用同时涉及到浏览器端和服务器端,之前的介绍除了简单提到了CSS规范之外,主要关注的是服务器端的技术发展。在客户端,1995年NetScape公司设计的JavaScript被用作浏览器上运行脚本语言为网页增加动态性。微软随后推出类似JScript,但是缺乏统一的语言规范,使得浏览器兼容性成为一个程序员的梦魇。JavaScript最终被提交到欧洲计算机制造商协会(ECMA),做为中立的ECMA开始了标准化脚本语言之路,并将其命名为ECMAScript。JavaScript可以响应浏览器端的用户事件,检测表单的正确性,动态修改HTML页面结构DOM,因此可以减少与服务器端的通信开销,并且做出很酷的页面动态效果。​2005年出现的AJAX这个概念使得JavaScript再次大放异彩​。AJAX即“Asynchronous JavaScript and XML”(异步的JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术,可以基于JavaScript的XmlHttpRequest的用于创建交互性更强​的Web应用。AJAX是一种已有技术的mashup,多种技术组合在一起形成了其特色和优势,早在1998年就已经开始有人使用。Google在地图和Gmail等产品中对这项技术的深入应用,以及AJAX这个吸引眼球的名字的提出,使其正式站在了聚光灯下,开始吸引无数人的目光。我们知道Web应用中用户提交表单时就向Web服务器发送一个请求,服务器接收并处理传来的表单,并返回一个新的网页。而前后两个页面中的往往大部分HTML代码是一样的,每次都返回整个页面内容是一种带宽资源的浪费。而AJAX应用仅向服务器发送并取回必须的数据,并在客户端采用JavaScript处理来自服务器响应,更新页面的局部信息。这样不仅浏览器和服务器的数据交换大大减少,而且客户端也可以更加快速地响应用户操作。如果你用Gmail就应该知道,Gmail从来都不刷新页面,所有的请求都是通过AJAX获取数据进行局部更新。AJAX的出现,以及诸如EXTJS、DOJO等一些前端开发框架的出现,也使得单页应用(Single Page Application)在这个时候流行起来。

前端MVC:Angular/Backbone

这种模式下,前后端的分工非常清晰,前后端的关键协作点是 Ajax 接口,规定好交互接口后,前后端工程师就可以根据约定,分头开工,开发环境中通过Mock等方式进行测试,同时在特定时间节点进行前后端集成测试。但是,随着业务功能的愈发复杂(看看现在的Gmail),这种模式本质上和JSP时代的Web开发并无本质区别,只不过是将复杂的业务逻辑从JSP文件转移到了JavaScript文件中而已。现在,对于一个前端功能、交互复杂的SPA,JavaScript代码很容易膨胀(超过10万行)。很自然地,像服务端从JSP向MVC框架转换的过程一样,前端开发也出现了大量的MVC框架,比较典型的包括BackboneJS, AngularJS, EmberJS, KnockoutJS。总的来说,MV*框架的提出是为了解决前端开发的复杂度,提供一套规则组织代码、分层(MVC),通过合理的组织和分层,前端的代码职责明确、清晰,便于开发与测试。

JavaScript在服务器端的逆袭:Node

各大浏览器的竞争,使其引擎的性能不断提升,至今Google V8引擎的性能已经足以运行大型Javascript程序。在V8之上加以网络、文件系统等内置模块,形成了如今的Node.js。

随着Node.js的出现,JavaScript开始拥有在服务端运行的能力,它的异步本质使得Node.js在处理I/O密集型业务中优势凸显,而大多Web业务中I/O性能都是瓶颈。eBay、Yahoo、甚至Microsoft Azure纷纷引入Node.js以提升性能。Node.js的package每天都有几千万的下载量。这对前端工程师来说可是一个好消息,精通JavaScript的他们也能够做服务端开发了!虽然现实中并不是这样美好(服务端开发涉及的不仅仅是语言层面),但一种新的开发模式也因此兴起:浏览器端处理展现层逻辑、而服务端Controller这一层以及相关的模板渲染、路由、数据接口以及Session/Cookie先关处理实际上交给了Nodejs来做。通过Nodejs, 意味着前后端很多代码可以复用(例如数据验证逻辑),在需要SEO的场景下也可以选择服务端模板渲染。

但另一方面,JavaScript刚被引入到服务器端开发,其生态环境还未成熟,甚至大量的常用package主版本号都是0。长期用来实现页面逻辑,天生自由的JavaScript,在服务器端开发中,仍未形成统一的开发范型。不同开发原则和编码风格的应用,都将对Node.js项目的性能、可维护性产生重大影响。现在而言,服务器端javascript开发究竟是魔鬼还是天使,仍取决于团队中的开发者。

结语

Web技术依然在快速发展,Web本身的基础规范也在不断完善,HTML5和CSS3引入了更多激动人心的特性。回顾Web的发展历史,从某个角度看,就是抽象层次不断提高的一个过程,更高的抽象层次屏蔽更低层的复杂性,从而提高开发效率。每当技术发展到一定程度,出现某些局限性的时候,就会有更优秀的技术出现来突破这些局限性。其实这是计算机技术发展的一个普遍规律,比如高级语言的出现屏蔽了汇编语言的复杂性,帮助我们更快速的编程;数据库技术的出现使得我们无需关心物理存储和访问细节,写简单的SQL语句就能搞定,更进一步,ORM框架使得我们通过一条语句调用一个类的一个方法就能方便就行数据操作。我们应该让自己的技术视野具备一定的高度和广度,看到一门技术的发展规律和发展历程,这是一种技术修养的体现,其实跟人文修养是一样的。同时也应该具有一定的深度,因为我们往往站在比较高的抽象层次,比如今天你写几行代码就能把数据库创建好,增删改查的功能也自动生成好了,但是成为高手需要你对底层的原理机制有更透彻的理解,真正遇到问题的时候才能抽丝剥茧迎刃而解。

来自:https://www.tianmaying.com/blog/8ab3eda84daf4e54014daf68ff09000b

web概述-javascript发展简史

“1994年,网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器,轰动一时。但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力。……网景公司急需一种网页脚本语言,使得浏览器可以与网页互动。”

 

网页脚本语言到底是什么语言?网景公司当时有两个选择:一个是采用现有的语言,比如Perl、Python、Tcl、Scheme等等,允许它们直接嵌入网页;另一个是发明一种全新的语言。

这两个选择各有利弊。第一个选择,有利于充分利用现有代码和程序员资源,推广起来比较容易;第二个选择,有利于开发出完全适用的语言,实现起来比较容易。

到底采用哪一个选择,网景公司内部争执不下,管理层一时难以下定决心。

3.

就在这时,发生了另外一件大事:1995年Sun公司将Oak语言改名为Java,正式向市场推出。

Sun公司大肆宣传,许诺这种语言可以”一次编写,到处运行”(Write Once, Run Anywhere),它看上去很可能成为未来的主宰。

网景公司动了心,决定与Sun公司结成联盟。它不仅允许Java程序以applet(小程序)的形式,直接在浏览器中运行;甚至还考虑直接将Java作为脚本语言嵌入网页,只是因为这样会使HTML网页过于复杂,后来才不得不放弃。

总之,当时的形势就是,网景公司的整个管理层,都是Java语言的信徒,Sun公司完全介入网页脚本语言的决策。因此,Javascript后来就是网景和Sun两家公司一起携手推向市场的,这种语言被命名为”Java+script”并不是偶然的。

4.

此时,34岁的系统程序员Brendan Eich登场了。1995年4月,网景公司录用了他。

Brendan Eich的主要方向和兴趣是函数式编程,网景公司招聘他的目的,是研究将Scheme语言作为网页脚本语言的可能性。Brendan Eich本人也是这样想的,以为进入新公司后,会主要与Scheme语言打交道。

仅仅一个月之后,1995年5月,网景公司做出决策,未来的网页脚本语言必须”看上去与Java足够相似”,但是比Java简单,使得非专业的网页作者也能很快上手。这个决策实际上将Perl、Python、Tcl、Scheme等非面向对象编程的语言都排除在外了。

Brendan Eich被指定为这种”简化版Java语言”的设计师。

5.

但是,他对Java一点兴趣也没有。为了应付公司安排的任务,他只用10天时间就把Javascript设计出来了。

由于设计时间太短,语言的一些细节考虑得不够严谨,导致后来很长一段时间,Javascript写出来的程序混乱不堪。如果Brendan Eich预见到,未来这种语言会成为互联网第一大语言,全世界有几百万学习者,他会不会多花一点时间呢?

总的来说,他的设计思路是这样的:

(1)借鉴C语言的基本语法;

(2)借鉴Java语言的数据类型和内存管理;

(3)借鉴Scheme语言,将函数提升到”第一等公民”(first class)的地位;

(4)借鉴Self语言,使用基于原型(prototype)的继承机制。

所以,Javascript语言实际上是两种语言风格的混合产物—-(简化的)函数式编程+(简化的)面向对象编程。这是由Brendan Eich(函数式编程)与网景公司(面向对象编程)共同决定的。

6.

多年以后,Brendan Eich还是看不起Java。

他说:

“Java(对Javascript)的影响,主要是把数据分成基本类型(primitive)和对象类型(object)两种,比如字符串和字符串对象,以及引入了Y2K问题。这真是不幸啊。”

把基本数据类型包装成对象,这样做是否可取,这里暂且不论。Y2K问题则是直接与Java有关。根据设想,Date.getYear()返回的应该是年份的最后两位:

  var date1 = new Date(1999,0,1);

var year1 = date1.getYear();

alert(year1); // 99

但是实际上,对于2000年,它返回的是100!

  var date2 = new Date(2000,0,1);

var year2 = date2.getYear();

alert(year2); // 100

如果用这个函数生成年份,某些网页可能出现”19100″这样的结果。这个问题完全来源于Java,因为Javascript的日期类直接采用了java.util.Date函数库。Brendan Eich显然很不满意这个结果,这导致后来不得不添加了一个返回四位数年份的Date.getFullYear()函数。

如果不是公司的决策,Brendan Eich绝不可能把Java作为Javascript设计的原型。作为设计者,他一点也不喜欢自己的这个作品:

“与其说我爱Javascript,不如说我恨它。它是C语言和Self语言一夜情的产物。十八世纪英国文学家约翰逊博士说得好:’它的优秀之处并非原创,它的原创之处并不优秀。’(the part that is good is not original, and the part that is original is not good.)”

不管怎么样,javascript诞生了,它的设计之初其实很简单,就是为了解决浏览器上表单提交的人机交互,而作为一种脚本语言,它天生的设计缺陷为后来的大型应用程序开发,留下了隐患。

石器时代

大约10年前(2007年左右),前端处在基于table(表格)布局的时代,有一家公司很出名,有三款产品,大家耳熟能详:

没错,就是Macromedia(后被adobe公司收购)和网页三剑客,所见即所得的编辑方式让开发者更关注于展示效果,而不去关注代码层的实现(这个时候语义化才刚刚兴起,table占据上风),那个时候没有前端后端之分,web工程师真的是“全栈”,写的了后端,套的了表格,查的了数据库,写的了js,js主要承载的作用是网页特效(对,如果有前端的话,其实也是写点特效),例如特效排行榜第一的“跑马灯”效果,类似这样的代码:

function scrollit(seed) {
		var m1 = "HI:你 好! ";
		var m2 = "欢迎访问一醉的知乎专栏";
		var m3 = "请 多 提 意 见,谢 谢!";
		var m4 = "/";
		var msg = m1 + m2 + m3 + m4;
		var out = " ";
		var c = 1;
		if (seed > 100) {
			seed--;
			cmd = "scrollit(" + seed + ")";
			timerTwo = window.setTimeout(cmd, 100);
		}
		else if (seed <= 100 && seed > 0) {
			for (c = 0; c < seed; c++) {
				out += " ";
			}
			out += msg;
			seed--;
			window.status = out;
			cmd = "scrollit(" + seed + ")";
			timerTwo = window.setTimeout(cmd, 100);
		}
		else if (seed <= 0) {
			if (-seed < msg.length) {
				out += msg.substring(-seed, msg.length);
				seed--;
				window.status = out;
				cmd = "scrollit(" + seed + ")";
				timerTwo = window.setTimeout(cmd, 100);
			}
			else {
				window.status = " ";
				timerTwo = window.setTimeout("scrollit(100)", 75);
			}
		}
	}

这样的代码,一般以内连方式放在页面的任何地方,就像一块一块的补丁,看了让人难受,不过还好,这个阶段很快就结束了(也许很多很烂的政府网站还在用table布局也说不定)。

铜器时代

1.2001年发布的ie6当时是世界上最先进的浏览器
2.2004年2月9日,Mozilla Firebird改称“Mozilla Firefox”,简称“Firefox”
3.在2006年年尾,微软发布了rebranded代号的Internet Explorer 7
4.北京时间2008年3月6日,微软发布了InternetExplorer 8的第一个公开测试版本(beta1)
5.Chrome beta测试版本在2008年9月2日发布

铜器时代,是令人悲伤的一个阶段,因为这个阶段终于有前端开发工程师这个职位了,但是主要工作居然是处理浏览器兼容性问题,下边是那个时代的浏览器情况,虽然ie6在2001年就发布了,但是它持续的时间太长,2012年貌似淘宝才不再兼容ie6(具体时间有待求证),大部分的时间,前端同学要兼容ie6,ie7,ie8,ie9,FF,chrome,safari…

大部分的css代码里边会有这样的熟悉的hack存在:

.hack{  
    background-color:red; /* All browsers */  
    background-color:blue !important;/* All browsers but IE6 */  
    *background-color:black; /* IE6, IE7 */  
    +background-color:yellow;/* IE6, IE7*/  
    background-color:gray\9; /* IE6, IE7, IE8, IE9, IE10 */  
    background-color:purple\0; /* IE8, IE9, IE10 */  
    background-color:orange\9\0;/*IE9, IE10*/  
    _background-color:green; /* Only works in IE6 */  
    *+background-color:pink; /*  WARNING: Only works in IE7 ? Is it right? */  
} 

那个时候的js代码已经不再内连在页面代码里,转而以文件的方式引入,类似这样:

<script src=“../your/code/a.js”></script>
<script src=“../your/code/b.js”></script>
<script src=“../your/code/c.js”></script>
<script src=“../your/code/d.js”></script>

但是,模块化,依旧毫无头绪,就像上边的代码,如果功能复杂的模块,维护起来难度较大,打包工具基本是借助别人家的ant或者YUI Compressor,前端工程师这个阶段的职责已经开始开发复杂的应用,另外值得注意的是后端MVC的架构开发模式逐渐成熟:

前端的架构模式呢?不知道在哪里..

铁器时代

2006年,jQuery诞生了,前端同学们奔走相告,喜极而泣,时至今日,jquery之所以这么成功,就是处理了大量的浏览器兼容性问题!

$('J_Hook').html('haha');

这样的代码让人重拾对web开发的乐趣,jQuery诞生之后,各种基于jQuery的组件扑天盖地而来,随着html5+css3的支持程度的加强,好日子终于来了。2010年随着模块加载器(LABjs、RequireJS、SeaJS)的涌现,前端开发的生产效率大幅低提高,前端真正可以去关注业务本身,而不用投入太多精力去处理兼容,处理模块关系了,前端的代码可能类似这样的了:

<script src=“js/jquery.min.js”></script>
<script src="js/require.js" data-main="js/main"></script>

随着2004年ajax技术的出现,异步加载/按需加载盛行起来,我亲身经历了2010~2014年淘宝瀑布流布局的兴起。那时候的前端的代码可能是这样的:

<!—— your dom element ——>
<div class=‘J_RenderCont’></div>

<!—— your javascript source ——>
<script src=“js/jquery.min.js”></script>
<script src="js/require.js" data-main="js/main"></script>

vm中很少的html 代码作为钩子(hook),大部分内容实用js异步渲染的方式在今天的大部分网站非常常见,并将持续很久。

蒸汽时代

终于来到了蒸汽时代,生产效率成数量级似的快速增长,这个时代有两件事,特别有历史意义:

1.2009年5月,Ryan Dahl在GitHub上发布了最初版本的部分Node.js包
2.2010年6月8日凌晨1点,史蒂夫·乔布斯在美国Moscone West会展中心举行的苹果全球开发者大会(WWDC 2010)上发布了苹果第四代手机iPhone4

第一件事,对于前端的意义是前端同学可以一个人搞定全栈开发了;

第二件事,对于前端的意义是前端同学可以开发在手机上访问的应用了;

前端迎来了一个逆天的时代,一个最美好的时代,一个基于nodejs开发的时代

1.Node.js是一个能够在服务器端运行JavaScript的开放源代码、跨平台JavaScript运行环境。
2.与Js语法相同,只是少了浏览器相关的环境(DOM,BOM之类)
3.核心模块包括文件系统I/O、网络(HTTP、TCP、UDP、DNS、TLS/SSL等)、二进制数据流、加密算法、数据流等等

那么nodejs都能做什么呢?

1.web框架:express koa
2.im及时聊天:Socket.IO
3.api包装:移动端,pc,h5
4.http proxy(淘宝首页)/ http proxy延伸,组装rpc服务,作为微服务的一部分
5.前端构建工具:grunt/gulp/bower/webpack/fis3..
6.OS:NodeOS
7.跨平台打包工具:nw.js、electron、cordova/phonegap
8.编辑器:atom,vscode

哦,为了给其他端工程师留点面子,我就不再列举下去了,你只需要知道阿特伍德定律就可以了:

any application that can be written in JavaScript, will eventually be written in JavaScript

nodejs给前端带来了空前强大的利好,智能手机却给前端带来了前所未有的挑战:

1.面向多终端的开发(pc端,移动端)
2.很多新概念产生:响应式设计 多端适配 ..
3.移动端js框架(库):zepto jquery-mobile kimi vue react
4.性能调优:首屏渲染 懒加载 webp 300ms延迟 css3/ canvas动画
5…

相比于pc端,手机端的硬件网络都受限,前端只能继续挖掘自身的经验并等待着手机硬件的加强(好消息是到17年,智能手机的硬件和依赖的网络情况越来越好)。

是选择native 还是 hybrid?No,我们有weex和react-native,抹平三端的差异已经是必然趋势,说不定未来(不远)的某一天,js已经可以直接搞定三端开发,调用系统硬件,处理流畅的动画和人机交互(之所以选择native开发,就是js目前还不能做到调取用户的硬件设备,比如摄像头;不能做到native体验一致的动画效果..,所以很多app采用hybrid的开发方式,做到妥协)。

说到这里,其实前端开发简史2017年之前的部分已经结束了,但是作为前端的一份子,我们可以大胆的憧憬一下下一个时代——基于js的生态时代。

基于js的生态时代

这个时代的典型特点是:js已经不再单纯的承担页面脚本的职责,她可以构建复杂的企业应用

各种细分领域,层出不穷,原来想也不敢想的事情,今天都可以用js去做,前端的未来10年将会是多彩纷呈的繁荣景象,现在已经有的领域:

web框架:

Vue.js

React – A JavaScript library for building user interfaces

Superheroic JavaScript MVW Framework

数据可视化:

D3.js – Data-Driven Documents

ECharts

Interactive JavaScript charts for your webpage

移动端打通:

Weex

React Native 中文网

桌面软件:

Electron

NW.js

游戏:

World’s #1 Open-Source Game Development Platform

VR/AR:

浅谈 WebVR – 在前端路上【专栏】 – SegmentFault

A-Frame – Make WebVR

three.js – Javascript 3D library

企业应用:

基于 Node.js 平台的 web 应用开发框架

Koa (koajs) — 基于 Node.js 平台的下一代 web 开发框架

egg – 为企业级框架和应用而生

硬件/物联网:

Ruff(我之前用ruff写过简单的上手指南 《ruff开发板初探》)

操作系统:

OS.js

其他:

最流行的编程语言JavaScript能做什么?

来自:https://zhuanlan.zhihu.com/p/29924966

https://blog.csdn.net/kese7952/article/details/79357868

 

web概述-前端发展简史

前端发展简史

起源

  • 1990 HTML 草创

1990 年,Tim Berners Lee 以超文本语言 HTML 为基础在 NeXT 电脑上发明了最原始的 Web 浏览器(“WorldWideWeb.app”)后来改名为Nexus,同时发明了第一个web服务器(“httpd“字样)。截至1990年底,第一个网页投放在开放的互联网上。

  • 1991 HTML1.0规范 发布

HTML 1.0首次亮相为SGML的混合体,其中包括“href”标签,将已经被广泛接受的文本标记语言与链接文档的能力结合起来。
•原始版本仅包含20个元素,其中13个元素仍然是HTML 4.01的一部分。

1991年8月6日,Tim Berners Lee在alt.hypertext新闻组贴出了一份关于World Wide Web的简单摘要: “WorldWideWeb(WWW)项目旨在允许在任何地方对任何信息进行全部链接。[…] WWW项目开始允许高能物理学家共享数据,新闻和文档。 我们非常有兴趣将网络传播到其他领域,并为其他数据提供网关服务器。 合作者欢迎!“
这标志了Web页面在Internet上的首次登场。最早Web主要被一帮科学家们用来共享和传递信息,全世界的Web服务器也就几十台。

与此同时,美国国家超算应用中心(National Center for Supercomputer Applications)对此表现出了浓厚的兴趣,并开发了名为 Mosaic 的浏览器,于 1993 年 4 月进行了发布。Mosaic 使得web开始流行起来,这便是曾经大名鼎鼎的Netscape Navigator的前身。

1993年 Tim Berners Lee建立了万维网联盟(World Wide Web Consortium,W3C),负责Web相关标准的制定。浏览器的普及和W3C的推动,使得Web上可以访问的资源逐渐丰富起来。这个时候Web的主要功能就是浏览器向服务器请求静态HTML信息。95年的时候马云在美国看到了互联网,更准确的说他其实看到的就是Web,阿里早先做的黄页也就是把企业信息通过进行HTML展示的Web应用。

1994 年 5 月,第一届万维网大会在日内瓦召开。

  • 1994.7 HTML 2.0 规范发布

HTML 2.0成为HTML的第一套官方标准 – 所有浏览器的测试基础标准,直到HTML 3.2。
•在Web爆炸期间,HTML 2.0被用作基准。
•1993年发布的其他浏览器包括Cello,Arena,Lynx,tkWWW和Mosaic。
•后来更名为Netscape Communications的Mosaic Communications根据美国国家超级计算应用中心(NCSA)Mosaic浏览器发布了Netscape,该浏览器是第一款带图形界面的商业网页浏览器。
• 亮点:根据Wired的Gary Wolfe的说法,Mosaic “正在成为世界标准界面 。”

1994 年 9 月,因特网工程任务组(Internet Engineering Task Force)设立了 HTML 工作组。

1994 年 11 月,Mosaic 浏览器的开发人员创建了网景公司(Netscape Communications Corp.),并发布了 Mosaic Netscape 1.0 beta 浏览器,后改名为 Navigator。

  • 1994 万维网联盟(World Wide Web Consortium)成立,简称 W3C

1994 年底,由Tim Berners Lee 牵头的万维网联盟(World Wide Web Consortium)成立,这标志着万维网的正式诞生。

此时的网页以 HTML 为主,是纯静态的网页,网页是“只读”的,信息流只能通过服务器到客户端单向流通,由此世界进入了 Web 1.0 时代。

  • 1995 网景推出 JavaScript

1995 年,网景工程师 Brendan Eich 花了10天时间设计了 JavaScript 语言。起初这种脚本语言叫做 Mocha,后改名 LiveScript,后来为了借助 Java 语言创造良好的营销效果最终改名为 JavaScript。网景公司把这种脚本语言嵌入到了 Navigator 2.0 之中,使其能在浏览器中运行。

与此相对的是,1996 年,微软发布了 VBScript 和 JScript。JScript 是对 JavaScript 进行逆向工程的实现,并内置于 Internet Explorer 3 中。但是 JavaScript 与 JScript 两种语言的实现存在差别,这导致了程序员开发的网页不能同时兼容 Navigator 和 Internet Explorer 浏览器。 Internet Explorer 开始抢夺 Netscape 的市场份额,这导致了第一次浏览器战争。

1996年 

•HTML现在支持表格,可以更好地控制表格信息的显示
•HTML还支持“客户端图像映射”文档元素,该元素允许单击图像的不同区域以引用不同的网络资源,如统一标识符(URI)所指定的。
•第一个CSS规范成为官方的W3C推荐标准,虽然已经完成,但是在任何Web浏览器达到接近完全规范的实现之前已经超过3年。
• 亮点: IE 3.0发布的功能等同于Netscape,它提供了脚本支持和市场上的第一个商业CSS实现。

第一次浏览器战争

1996 年 11 月,为了确保 JavaScript 的市场领导地位,网景将 JavaScript 提交到欧洲计算机制造商协会(European Computer Manufacturers Association)以便将其进行国际标准化。

  • 1996.12 W3C 推出了 CSS 1.0 规范

1997年
•经过研究人员的激烈争论,研究人员认为文本属性(如背景颜色和纹理,字体大小和字体)正在将HTML从根部移开,以便组织而不是修饰文档以供共享; 并且在IE和Netscape之间的浏览器战争中,HTML 3.2(代码名称WILBUR)被批准。
•获得批准的让步包括Internet Explorer阵营和Netscape阵营同意杀死他们专有的<marquee>和<​​blink>属性,这些属性负责我们知道并讨厌的引人注目,闪烁的文本。
•这是网页中广泛过度使用帧的时间,这是互联网上最糟糕的失误之一,仅次于自动播放midi文件。
• 突出显示:已集成到Microsoft Windows中的IE 4.0版本不鼓励用户使用竞争的浏览器,因为默认情况下IE是在那里。

  • 1997.1 HTML3.2 作为 W3C 推荐标准发布
  • 1997.6 ECMA 以 JavaScript 语言为基础制定了 ECMAScript 1.0 标准规范

1997 年 6 月,ECMA 以 JavaScript 语言为基础制定了 ECMAScript 标准规范 ECMA-262。JavaScript 是 ECMAScript 规范最著名的实现之一,除此之外,ActionScript 和 JScript 也都是 ECMAScript 规范的实现语言。自此,浏览器厂商都开始逐步实现 ECMAScript 规范。

1998年
•Cougar是成为HTML 4.0的代码名称,在1997年底发布为推荐,最终被批准为HTML 4.01。
•此版本包含层叠样式表(CSS),这是控制表示元素(如颜色,字体和背景)的更简单方法。 (对啊 ,简单来说  CSS1.0 是 table td布局,CSS2.0 是div li布局,学校里压根都没有提到  )
• 亮点: Netscape在“浏览器战争”中被击败,被美国在线以42亿美元收购。

  • 1997.12 HTML 4.0 规范发布
  • 1998 W3C 推出了 CSS 2.0 规范
  • 1998.6 ECMAScript 2 规范发布

1998 年 6 月,ECMAScript 2 规范发布,并通过 ISO 生成了正式的国际标准 ISO/IEC 16262 。

  • 1999.12 ECMAScript 3 规范发布

1999 年 12 月,ECMAScript 3 规范发布,在此后的十年间,ECMAScript 规范基本没有发生变动。ECMAScript 3 成为当今主流浏览器最广泛使用和实现的语言规范基础。

第一次浏览器战争以 IE 浏览器完胜 Netscape 而结束,IE 开始统领浏览器市场,份额的最高峰达到 2002 年的 96%。随着第一轮大战的结束,浏览器的创新也随之减少。

2000
•HTML和XML联手成为XHTML,挑选严格的XML代码结构来执行更清晰的代码,但由于它不向后兼容,因此需要重写代码。
尽管XML是标准的,但大多数浏览器原谅了这一点,并且仍然允许使用潦草的代码,大写代码和不正确的封闭标签,以致难以广泛采用更严格的XML代码。
•问:为什么XHTML鸟无效? 答:因为它没有正确嵌套。
• 突出显示: IE是占主导地位的浏览器,在2002年达到网络浏览器使用份额的约96%的峰值,超过Netscape的高峰。

XHTML

  • 1999 W3C 发布 HTML 4.01 标准,同年微软推出用于异步数据传输的 ActiveX,随即各大浏览器厂商模仿实现了 XMLHttpRequest(AJAX 雏形)。
  • 2000: W3C 采用了一个大胆的计划,把 XML 引入 HTML,XHTML1.0 作为 W3C 推荐标准发布
  • 2001.5 W3C 推出了 CSS 3.0 规范草案
  • 2002-2006 XHTML 2.0 最终放弃
  • 2009 W3C 宣布 XHTML2.0 不再继续,宣告死亡

2002年
•许多人对杂乱的编码实践表 (table布局)示批评,(div布局)无表设计的想法开始增长。
•术语“无表设计”意味着使用CSS而不是布局表来定位页面上的HTML元素。
•在网页中显示表格信息时,HTML表格仍然有其合法的位置。
•这也是分享和交换特别内容(如Weblogs和RSS)的新想法迅速获得采用并被命名为“Web 2.0”的时候。
• 亮点:第一次浏览器大战结束,IE浏览器没有对其市场份额进行严重的竞争 – 这为Web浏览器的快速创新带来了一段时间。

web1.0:网络-人(单向信息,只读,eg个人网站,大英百科全书);
web2.0:人-人(以网络为沟通渠道进行人与人沟通,eg维基、博客);
web3.0:人-网络-人(人工智能、关联数据和语义网络构建,形成人和网络以及网络与人的沟通,同时在SEO支持下,提高人与人沟通的便利性)

我对三者的区别在于三个时期中网络的角色——web1.0网络是信息提供者,单向性的提供和单一性理解;web2.0网络是平台,用户提供信息,通过网络,其他用户获取信息;web3.0网络成为用户需求理解者和提供者,网络对用户了如指掌,知道用户有什么、要什么以及行为习惯,进行资源筛选、智能匹配,直接给用户答案。

动态页面的崛起

JavaScript 诞生之后,可以用来更改前端 DOM 的样式,实现一些类似于时钟之类的小功能。那时候的JavaScript 仅限于此,大部分的前端界面还很简单,显示的都是纯静态的文本和图片。这种静态页面不能读取后台数据库中的数据,为了使得 Web 更加充满活力,以 PHP、JSP、ASP.NET 为代表的动态页面技术相继诞生。

PHP(PHP:Hypertext Preprocessor)最初是由 Rasmus Lerdorf 在 1995 年开始开发的,现在PHP 的标准由 PHP Group 维护。PHP 是一种开源的通用计算机脚本语言,尤其适用于网络开发并可嵌入 HTML 中使用。PHP 的语法借鉴吸收 C 语言、Java 和 Perl 等流行计算机语言的特点,易于一般程序员学习。PHP 的主要目标是允许网络开发人员快速编写动态页面。

JSP(JavaServer Pages)是由 Sun 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,从而动态生成 HTML、XML 或其他格式文档的 Web 网页的技术标准。JSP 技术是以 Java 语言为基础的。1999 年,JSP 1.2 规范随着 J2EE 1.2 发布。

ASP(Active Server Pages)1.0 在 1996 年随着 IIS 3.0 而发布。2002 年,ASP.NET 发布,用于替代 ASP。

随着这些动态服务器页面技术的出现,页面不再是静止的,页面可以获取服务器数据信息并不断更新。以 Google 为代表的搜索引擎以及各种论坛相继出现,使得 Web 充满了活力。

随着动态页面技术的不断发展,后台代码变得庞大臃肿,后端逻辑也越来越复杂,逐渐难以维护。此时,后端的各种 MVC 框架逐渐发展起来,以 JSP 为例,Struct、Spring 等框架层出不穷。

从 Web 诞生至 2005 年,一直处于后端重、前端轻的状态。

2005年
•Ajax是一种可追溯到IE 4的iFrame的技术,它使网页更快地请求和更新动态页面内容,以响应像桌面应用程序,如Rackspace Email和Gmail等云应用程序以及社交媒体网站Digg,Facebook和Twitter; 和在线内容管理系统(CMS),如WordPress。
•2005年,Adaptive Path使用Ajax作为与客户谈论Asynchronous JavaScript + CSS + DOM + XMLHttpRequest的更简单方法
• 突出显示:浏览器大战再次启动,Mozilla在2004年发布Firefox 1.0; 从那以后,Firefox继续获得越来越多的浏览器市场份额。

  • AJAX 的流行

在 Web 最初发展的阶段,前端页面要想获取后台信息需要刷新整个页面,这是很糟糕的用户体验。

Google 分别在 2004 年和 2005 年先后发布了两款重量级的 Web 产品:Gmail 和 Google Map。这两款 Web 产品都大量使用了 AJAX 技术,不需要刷新页面就可以使得前端与服务器进行网络通信,这虽然在当今看来是理所应当的,但是在十几年前AJAX却是一项革命性的技术,颠覆了用户体验。

随着 AJAX 的流行,越来越多的网站使用 AJAX 动态获取数据,这使得动态网页内容变成可能,像 Facebook 这样的社交网络开始变得繁荣起来,前端一时间呈现出了欣欣向荣的局面。

AJAX 使得浏览器客户端可以更方便地向服务器发送数据信息,这促进了 Web 2.0 的发展。

Google Trend: AJAX 从 2005 年开始得到开发人员的广泛关注。

  • 2006 XMLHttpRequest 被 W3C 正式纳入标准。

第二次浏览器大战

  • 前端兼容性框架的出现

IE 在第一次浏览器大战中击败 Netscape 赢得胜利,垄断了浏览器市场。作为独裁者,IE 并不遵循 W3C 的标准,IE 成了事实标准。

Netscape 于 1998 年被 AOL 收购前创建了 Mozilla 社区,Firefox 于 2004 年 11 月首次发布,并且 9 个月内下载量超过 6000 万,获取了巨大的成功,IE 的主导地位首次受到了挑战, Firefox 被认为是 Netscape 的精神续作。

之后 Firefox 浏览器一路奋起直追,逐渐蚕食 IE 市场份额,这引发了第二次浏览器战争。在 2008 年底时,Firefox 的市场份额达到了 25% 以上,IE 则跌至 65% 以下。

第二次浏览器战争中,随着以 Firefox 和 Opera 为首的 W3C 阵营与 IE 对抗程度的加剧,浏览器碎片化问题越来越严重,不同的浏览器执行不同的标准,对于开发人员来说这是一个恶梦。

为了解决浏览器兼容性问题,Dojo、jQuery、YUI、ExtJS、MooTools 等前端 Framework 相继诞生。前端开发人员用这些 Framework 频繁发送 AJAX 请求到后台,在得到数据后,再用这些 Framework 更新 DOM 树。

其中,jQuery 独领风骚,几乎成了所有网站的标配。Dojo、YUI、ExtJS 等提供了很多组件,这使得开发复杂的企业级 Web 应用成为可能。

Google Trend: 蓝色 jQuery,红色 Dojo,绿色 YUI,紫色 ExtJS,黄色 MooTools

HTML 5

1999年,W3C发布了 HTML 4.01 版本,在之后的几年,没有再发布更新的 Web 标准。随着Web的迅猛发展,旧的Web标准已不能满足 Web 应用的快速增长。

2004 年 6 月,Mozilla 基金会和 Opera 软件公司在万维网联盟(W3C)所主办的研讨会上提出了一份联合建议书,其中包括 Web Forms 2.0 的初步规范草案。建议举行一次投票,以表决 W3C 是否应该扩展 HTML 和 DOM,从而满足 Web 应用中的新需求。研讨会最后以 8 票赞成,14 票反对否决此建议,这引起一些人的不满,不久后,部分浏览器厂商宣布成立网页超文本技术工作小组(WHATWG),以继续推动该规范的开发工作,该组织再度提出 Web Applications 1.0 规范草案,后来这两种规范合并形成 HTML5。2007 年,获得 W3C 接纳,并成立了新的 HTML 工作团队。2008 年 1 月 22 日,第一份正式草案发布。

2008年
•由于缺乏对XHTML中丰富Web应用程序的关注,Web超文本应用技术(WHAT)工作组于2004年与Apple,Mozilla和Opera成员形成了这个协议,并在四年后发布了第一份HTML5草案。
•到2009年,XHTML开发团队进行反汇编,加入HTML5阵营。
•至少2022年前,HTML5不会成为标准,但Firefox和IE9已经支持其某些功能。 与大多数新版本的HTML一样,它的优势只会与其开发者和浏览器支持一样强大。
• 突出显示: Google发布适用于Windows的Chrome浏览器。 Chrome在09年10月份获得了3.6%的使用份额,并在Mac OS X和Linux测试版发布后迅速增长。

  • 2008.12 Chrome 发布,JavaScript 引擎 V8

HTML5 草案发布不久,Google 在 2008 年 12 月发布了 Chrome 浏览器,加入了第二次浏览器大战当中。Chrome 使用了 Safari 开源的 WebKit 作为布局引擎,并且研发了高效的 JavaScript 引擎 V8。

尽管 HTML5 在网络开发人员中非常出名了,但是它成为主流媒体的一个话题是在 2010 年的 4 月,当时苹果公司的 CEO 乔布斯发表一篇题为“对 Flash 的思考”的文章,指出随着 HTML5 的发展,观看视频或其它内容时,Adobe Flash 将不再是必须的。这引发了开发人员间的争论,包括 HTML5 虽然提供了加强的功能,但开发人员必须考虑到不同浏览器对标准不同部分的支持程度的不同,以及 HTML5 和 Flash 间的功能差异。

2010
•2010年,史蒂夫乔布斯宣布苹果产品将不再支持Flash,原因包括其专有的代码和安全漏洞,并推动HTML5的音频和视频播放功能的发展成为众人关注的焦点。
•将Flash和HTML5结合为人们分享用户生成的视频提供了一个免费空间的YouTube在2005年推出后每天提供约20亿视频。
• 突出显示: StatCounter报告说,在统计单个浏览器版本时,Firefox 3.5是最流行的浏览器,IE 7和8其次。

在第二次浏览器大战中,各个浏览器厂商都以提升 JavaScript 运行效率和支持 HTML5 各种新特性为主要目标,促进了浏览器的良性竞争。在这一场战争中,Chrome 攻城略地,抢夺 IE 市场份额。2013 年,Chrome 超过 IE,成为市场份额最高的浏览器。2016 年,Chrome 占据了浏览器市场的半壁江山。

全球浏览器市场份额(2009-2017)

自 2008 年以来,浏览器中不断支持的 HTML5 新特性让开发者激动不已:WebWorker 可以让 JavaScript 运行在多线程中,WebSocket 可以实现前端与后台的双工通信,WebGL 可以创建 Web3D 网页游戏……

桌面浏览器对 HTML5 支持程度(2009-2017)

  • 2009.12 ECMAScript 5.0 规范发布
  • 2011.6 ECMAScript 5.1 规范发布
  • 2012.10 微软发布 TypeScript 公开版

TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。

TypeScript 扩展了 JavaScript 的语法,所以任何现有的 JavaScript 程序可以不加改变的在 TypeScript 下工作。TypeScript 是为大型应用之开发而设计,而编译时它产生 JavaScript 以确保兼容性。

  • 2013.6.19 TypeScript 0.9 正式版
  • 2014.10.28 W3C 正式发布 HTML 5.0 推荐标准

2014 年 10 月 28 日,W3C 正式发布 HTML 5.0 推荐标准。

Node.js 的爆发

早在 1994 年,Netspace 就公布了其 Netspace Enterprise Server 中的一种服务器脚本实现,叫做 LiveWire,是最早的服务器端 JavaScript,甚至早于浏览器中的 JavaScript。对于这门图灵完备的语言,Netspace 很早就开始尝试将它用在后端。

微软在 1996 年发布的 IE 3.0 中内嵌了自己的 JScript语言,其兼容 JavaScript 语法。1997 年年初,微软在它的服务器 IIS 3.0 中也包含了 JScript,这就是我们在 ASP 中能使用的脚本语言。

1997 年,Netspace 为了用 Java 实现 JavaScript 而创建了 Rhino 项目,最终 Rhino 演变成一个基于 Java 实现的 JavaScript 引擎,由 Mozilla 维护并开源。Rhino 可以为 Java 应用程序提供脚本能力。2006 年 12 月,J2SE 6 将 Rhino 作为 Java 默认的脚本引擎。

SpiderMonkey 是 Mozilla 用 C/C++ 语言实现的一个 JavaScript 引擎,从 Firefox 3.5 开始作为 JavaScript 编译引擎,并被 CouchDB 等项目作为服务端脚本语言使用。

可以看到,JavaScript 最开始就能同时运行在前后端,但时在前后端的待遇却不尽相同。随着 Java、PHP、.Net 等服务器端技术的风靡,与前端浏览器中的 JavaScript 越来越流行相比,服务端 JavaScript 逐渐式微。

2008 年 Chrome 发布,其 JavaScript 引擎 V8 的高效执行引起了 Ryan Dahl 的注意。2009 年,Ryan 利用 Chrome 的 V8 引擎打造了基于事件循环的异步 I/O 框架 —— Node.js 诞生。

Node.js 具有以下特点:

  • 基于事件循环的异步 I/O 框架,能够提高 I/O 吞吐量
  • 单线程运行,能够避免了多线程变量同步的问题
  • 使得 JavaScript 可以编写后台代码,前后端编程语言统一。

Node.js 的出现吸引了很多前端开发人员开始用 JavaScript 开发服务器代码,其异步编程风格也深受开发人员的喜爱。Node.js 的伟大不仅在于拓展了 JavaScript 在服务器端的无限可能,更重要的是它构建了一个庞大的生态系统。

2010 年 1 月,NPM 作为 Node.js 的包管理系统首次发布。开发人员可以按照 CommonJS 的规范编写 Node.js 模块,然后将其发布到 NPM 上面供其他开发人员使用。目前 NPM 具有 40 万左右的模块,是世界上最大的包模块管理系统。

2016 年常见包管理系统模块数量,NPM 高居榜首

Node.js 也催生了 node-webkit 等项目,用 JavaScript 开发跨平台的桌面软件也成为可能。Node.js 给开发人员带来了无穷的想象,JavaScript 大有一统天下的趋势。

前端 MV* 架构

随着 HTML5 的流行,前端不再是人们眼中的小玩意,以前在 C/S 中实现的桌面软件的功能逐步迁移到了前端,前端的代码逻辑逐渐变得复杂起来。

以前只用于后台的 MV* 等架构在前端逐渐使用起来,以下列举了部分常用的 MV* 框架。

随着这些 MV* 框架的出现,网页逐渐由 Web Site 演变成了 Web App,最终导致了复杂的单页应用( Single Page Application)的出现。

移动 Web 和 Hybrid App

随着 iOS 和 Android 等智能手机的广泛使用,移动浏览器也逐步加强了对 HTML5 特性的支持力度。

移动浏览器对 HTML5 支持程度(2009-2017)

移动浏览器的发展,导致了流量入口逐渐从 PC 分流到移动平台,这是 Web 发展的新机遇。移动 Web 面临着更大的碎片化和兼容性问题,jQuery Mobile、Sencha Touch、Framework7、Ionic 等移动 Web 框架也随之出现。

相比于 Native App,移动 Web 开发成本低、跨平台、发布周期短的优势愈发明显,但是 Native App的性能和 UI 体验要远胜于移动 Web。移动 Web 与 Native App 孰优孰劣的争论愈演愈烈,在无数开发者的实践中,人们发现两者不是替代关系,而是应该将两者结合起来,取长补短,Hybrid 技术逐渐得到认同。

Hybrid 技术指的是利用 Web 开发技术,调用 Native 相关 API,实现移动与 Web 二者的有机结合,既能体现 Web 开发周期短的优势,又能为用户提供 Native 体验。

根据实现原理,Hybrid 技术可以分为两大类:

  1. 将 HTML 5 的代码放到 Native App 的 WebView 控件中运行,WebView 为 Web 提供宿主环境,JavaScript 代码通过 WebView 调用 Native API。典型代表有 PhoneGap(Cordova) 以及国内的 AppCan 等。
  2. 将 HTML 5 代码针对不同平台编译成不同的原生应用,实现了 Web 开发,Native 部署。这一类的典型代表有 Titanium 和 NativeScript。

Hybrid 一系列技术中很难找出一种方案适应所有应用场景,我们需要根据自身需求对不同技术进行筛选与整合。

ECMAScript 6

JavaScript 语言是 ECMAScript 标准的一种实现,截止 2017 年 2 月,ECMAScript 一共发布了 7 个版本。

1997 年 6 月, ECMAScript 1.0 标准发布。

1998 年 6 月,ECMAScript 2.0 发布。

1999 年 12 月,ECMAScript 3.0 发布。

2007 年 10 月,Mozilla 主张的 ECMAScript 4.0 版草案发布,对 3.0 版做了大幅升级,该草案遭到了以 Yahoo、Microsoft、Google 为首的大公司的强烈反对,JavaScript 语言的创造者 Brendan Eich 和 IE 架构师 Chris Wilson 甚至在博客上就ES4向后兼容性问题打起了口水仗,最后由于各方分歧太大,ECMA 开会决定废弃中止 ECMAScript 4.0 草案。经各方妥协,在保证向下兼容的情况下,将部分增强的功能放到 ECMAScript 3.1 标准中,将原有 ECMAScript 4.0 草案中激进的功能放到以后的标准中。不久,ECMAScript 3.1 就改名为 ECMAScript 5。

2009 年 12 月,本着’Don’t break the web’原则,ECMAScript 5 发布。新增了 strict 模式、属性 getter 和 setter 等。

2011 年 6 月,ECMAScript 5.1 发布。

2015 年 6 月,ECMAScript 6.0 发布。该版本增加了许多新的语法,包括支持 let、const、Arrow function、Class、Module、Promise、Iterator、Generator、Set、Map、async、Symbol、Proxy、Reflect、Decorator 等。TC39 委员会计划以后每年都发布一个新版本的 ECMAScript,所以 ECMAScript 6.0 改名为 ECMAScript 2015。

2016 年 6 月,在 ECMAScript 2015 的基础上进行了部分增强,发布了 ECMAScript 2016。

在 ECMAScript 的各个版本中,ECMAScript 6.0 无疑最受人瞩目的,它增加了许多新特性,极大拓展了 JavaScript 语法和能力,以至于许多浏览器都只能支持部分 ES6 中的新特性。随之,Babel 和 TypeScript 逐渐流行起来,编写 ES6 代码,然后用 Babel 或 TypeScript 将其编译为 ES5 等浏览器支持的 JavaScript。

ECMAScript 以后每年将会发布一个新版本,这无疑将持续促使浏览器厂商不断为 JavaScript 注入新的功能与特性,JavaScript走上了快速发展的正轨。

参考资料

更多文章

https://github.com/jeanboydev/Android-ReadTheFuckingSourceCode

来自:https://blog.csdn.net/freekiteyu/article/details/79927047

https://blog.rackspace.com/internet-history-html-evolution

等等

科学上网-零基础搭建个人专线shadowsocks

一、首先购买一个海外vps ,安装centos7系统

VPS有:BandwagonHost,dataocean,vultr,linode。选择服务器地址时,可以先测试一下速度,选速度快的机房。

二、登录vps 并加固

1、利用SSH远程 登入 centos7,方便后续操作。(有些vps的ip可能被屏蔽了,所以需要换一个vps试试看)
SSH远程连接入门

2、加固 centos7 安全性:

(1)、更新centos7系统
(2)、解决系统编码问题
(3)、开启 防火墙。

systemctl start firewalld

(4)、修改SSH默认端口SSH只用密钥登录

3、安装VNC软件,进行远程访问。(可选操作,如果不适应用命令行操作,可以借助vnc 进行远程桌面操作)
(为了提高安全性,使用SSH端口转发,登入服务器)
vnc远程连接配置与入门

三、安装shadowsocks服务端

我们安装的是python版本的。因为centos7 默认自带了 python,所以不需要安装了。如果没有安装的话,可以运行

yum install python

这样子 也可以检查出,是否安装了python。

安装 pip :
1、可以用 VNC 远程登录 vps 主机,然后用浏览器 下载 pip 安装包。
下载页面:https://pypi.org/project/pip/9.0.1/
文件链接地址:https://files.pythonhosted.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz

为什么不选最新版,因为最新版pip 和 python 有一点 兼容性问题。
也可以在SSH中用命令行的方式 下载文件:

curl https://files.pythonhosted.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz -o pip.tar.gz --progress

文件下载完,可以用 VNC 桌面方式进行 解压。或者 在 SSH 中 用命令行 进行解压。

tar zxvf pip-9.0.1.tar.gz -C /root/mydir

将文件 解压到了mydir目录下面。
解压完成后,进入 mydir 文件夹。可以用vnc 直接进入。也可以用命令行

cd /root/mydir

只有进入到 mydir文件夹以后,下面的安装才能成功。
在SSH下或者vnc的终端运行命令行:

python setup.py install

(其实 用命令行 可以直接装 pip,但是安装的是最新版的pip,好像与python存在兼容性问题)

curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
python get-pip.py

2.安装 shadowsocks
在SSH或者VNC的终端下运行如下代码:

安装 加密软件 库 用于支持 aes-256-gcm 加密方式 (带#的,都是注释,不需要打 )
 yum install epel-release
 
yum install libsodium
 安装 或升级 最新 软件 版本
 pip install --upgrade git+https://github.com/shadowsocks/shadowsocks.git@master

3.配置shadowsocks
SSH下:

[bash] # 创建 /etc/shadowsocks.json vim /etc/shadowsocks.json [/bash]

上面就创建了配置文件,然后用 vim 编辑 下面内容就行了。

{
"server": "0.0.0.0",
"server_port": 3678,
"password": "sdfsndsfoni",
"method": "aes-256-cfb"
}

多余多个端口可以如下:(顺便说了一下,可以添加PID_FILE和LOG_FILE)

pidfile

{
  "server": "0.0.0.0",
  "port_password": {
        "8850":"hehe2016"
 },
  "method": "aes-256-gcm",
  "PID_FILE": "/var/run/shadowsocks_ssserver.pid",
  "LOG_FILE": "/var/run/shadowsocks_ssserver.log"
}

添加PID_FILE,是因为 执行下面这句话时,需要PID 文件,否则会报错。

ssserver -c /etc/shadowsocks.json -d  stop

这个时候,服务器就可以使用了:

##### 开启 shadowsocks  服务
ssserver -c /etc/shadowsocks.json -d  stop

##### 关闭 shadowsocks  服务
ssserver -c /etc/shadowsocks.json -d  start

后面提到的shadowsocks.service是另一种启动方式。

##### 查看 shadowsocks 状态 
#####(如果 我用ssserver -c /etc/shadowsocks.json -d start 启动,那么这里查看的启动状态是 dead 的,两种启动方法 应该隶属于 不同的管理方式中)
systemctl status shadowsocks

##### 启动 shadowsocks 服务
systemctl start shadowsocks

##### 关闭 shadowsocks 服务
systemctl stop shadowsocks

注意: 加密方式(method),密码(password),服务器端口(server-port)都可以自己设置,只要客户端相同就行。服务器端口 1024以下是系统保留的,从1024-65535是用户使用的。密码 建议选择 aes 系列。method为加密方法,可选aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb, rc4-md5, chacha20, salsa20, rc4, table

vim编辑器用法可以查看:vim入门基础
VNC桌面环境就直接创建json文件就行了。

4.配置开机自启动。SSH和VNC操作都行。

新建启动脚本文件/etc/systemd/system/shadowsocks.service,内容如下:

[Unit]
Description=Shadowsocks
[Service]
TimeoutStartSec=0
ExecStart=/usr/bin/ssserver -c /etc/shadowsocks.json
[Install]
WantedBy=multi-user.target

然后 , 在SSH或者VNC终端下:输入命令

systemctl enable shadowsocks
systemctl start shadowsocks

为了检查 shadowsocks 服务是否已成功启动,可以继续执行以下命令查看服务的状态:

systemctl status shadowsocks -l 

如果服务启动成功,则控制台显示的信息可能类似这样:

● shadowsocks.service - Shadowsocks
 Loaded: loaded (/etc/systemd/system/shadowsocks.service; enabled; vendor preset: disabled)
 Active: active (running) since Mon 2015-12-21 23:51:48 CST; 11min ago
 Main PID: 19334 (ssserver)
 CGroup: /system.slice/shadowsocks.service
 └─19334 /usr/bin/python /usr/bin/ssserver -c /etc/shadowsocks.json
 Dec 21 23:51:48 morning.work systemd[1]: Started Shadowsocks.
 Dec 21 23:51:48 morning.work systemd[1]: Starting Shadowsocks…
 Dec 21 23:51:48 morning.work ssserver[19334]: INFO: loading config from /etc/shadowsocks.json
 Dec 21 23:51:48 morning.work ssserver[19334]: 2015-12-21 23:51:48 INFO loading libcrypto from libcrypto.so.10
 Dec 21 23:51:48 morning.work ssserver[19334]: 2015-12-21 23:51:48 INFO starting server at 0.0.0.0:8388

不过此时还连接不上服务器,因为CentOS 7默认防火墙是阻止SS端口的,这里需要放行SS端口,由于CentOS 7的防火墙升级为Firewall了,操作方式与之前的iptables有所不同(3678为文中shadowsocks服务器配置端口号,这里要改为你安装SS时设置的端口):
firewall-cmd –permanent –add-port=3678/tcp
firewall-cmd –reload

四、安装kcp加速插件

由于原生shadowsocks速度慢,所以用kcp 插件加速。
访问链接,选择linux-amd64 下载,centos7系统 是 64位的linux系统。
https://github.com/shadowsocks/shadowsocks-windows/releases

解压后有两个文件,其中类似server_linux_amd64这样的文件就是服务端程序了,另一个类似client_linux_amd64的就是客户端程序了。如果客户端在Windows上使用要下载Windows版本的哦。

SSH 里面可以用 tar命令进行解压(前面解压pip文件已经提到过了), ls 命令可以查看 当前目录所有文件 cd 命令表示进入某目录。可以搜索一下bash常用命令操作。
VNC里面直接可视化操作就行了。

先来创建服务端配置文件,创建开机启动项如下供参考:

[bash] vim /etc/systemd/system/kcptun.service [/bash]

然后 配置启动文件如下:

[Unit]
 Description=kcptun
 [Service]
 TimeoutStartSec=20
 ExecStart=/usr/bin/server_linux_amd64 -t "0.0.0.0:3678" -l ":5678" -mode fast2
 [Install]
 WantedBy=multi-user.target

其中TimeoutStartSec为延时启动的时间,这里由于需要等待ShadowSocks启动完成后再启动,所以配置20秒的延迟。ExecStart后的server_linux_amd64为你刚刚下载的文件的位置,建议放到相应的文件夹以便管理。-t后的是服务器的IP和ShadowSocks服务的端口,这里IP配置为本机IP即可。-l表示KCP服务使用的端口,-mode表示速度的模式,从快到慢依次是fast3 > fast2 > fast > normal > default,fast3一般用于游戏,不想要任何的延迟(no lag),但这也意味浪费的流量会增多,这里我选择fast2就够用了。

[bash] systemctl daemon-reload # 创建开机启动 systemctl enable kcptun # 启动kcp服务。 systemctl start kcptun # 防火墙 开放 kcp 端口 (kcp 是 udp 协议,shadowsocks 是tcp协议) firewall-cmd –permanent –add-port=5678/udp # 防火墙 重新 加载 配置 firewall-cmd –reload [/bash]

五、安装客户端

安卓版本:(个人用 3.3.1 版本,因为 好像 不需要 google play 插件吧。并且内置kcp 插件)
https://github.com/shadowsocks/shadowsocks-android/releases
windows版本:
https://github.com/shadowsocks/shadowsocks-windows/releases
需要下载kcp客户端单独进行集成。(Windows-386 32位系统,Windows-amd64 64位系统)
https://github.com/xtaci/kcptun/releases
集成方法可以参考链接:
(总体思路是本地shadowsocks先连接本地的kcptun,然后kcptun 连接 代理服务器的 kcptun,
接着 代理服务器的kcptun 连接 代理服务器的 shadowsocks)
https://blog.csdn.net/farawayzheng_necas/article/details/63255799

mac版本:(内置kcp插件)
https://github.com/shadowsocks/ShadowsocksX-NG
ios版本:
因为大陆已经下架,需要在其他地区搜索:Shadowrocket 等 支持shadowsocks的 应用软件。

之前3.几的安卓客户端,kcp与客户端是集成的,配置文件中,shadowsocks服务器端口就填shadowsocks端口。kcp配置:需要配置kcp端口,kcp参数:

--crypt aes-192 --key "hello"

到了安卓4.x版本,kcp是插件化了。无法启动kcp,可能是1、shadowsocks卸载重装2、手机管家的自启动的链式启动,允许kcptun。

如果要添加kcp插件,那么shadowsocks的端口就要填 kcp的端口,kcp的插件需要配置:[注意与3.x的配置不同,这里的密码,不再需要添加引号了]

key=hello;crypt=aes-192

六、安装obfs 混淆,这个只能与 kcp 二选一

服务器:centos

sudo yum install gcc autoconf libtool automake make zlib-devel openssl-devel asciidoc xmlto

git clone https://github.com/shadowsocks/simple-obfs.git
cd simple-obfs
git submodule update --init --recursive
./autogen.sh
./configure && make
sudo make install

### 会报错 缺少 libev,于是 猜测 shadowsocks libev版本有,
### 于是安装 shadowsocks libev 的依赖库
yum install gcc gettext autoconf libtool automake make pcre-devel asciidoc xmlto c-ares-devel libev-devel libsodium-devel mbedtls-devel -y

服务器配置:

因为是独立模式:vim /etc/systemd/system/obfs-server.service

[Unit]
Description=Simple-obfs
After=network.target

[Service]
Type=simple-obfs
User=nobody
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ExecStart=/usr/local/bin/obfs-server -s 0.0.0.0 -p 443 --obfs tls -r 127.0.0.1:8866

[Install]
WantedBy=multi-user.target

监听 1024以下端口 需要 root 用户权限,所以采用下面的方法:(应该是绑定服务吧)

setcap cap_net_bind_service=+ep /usr/local/bin/obfs-server
### 最后更新服务并启动:
sudo systemctl enable obfs-server
sudo systemctl daemon-reload
sudo systemctl restart obfs-server

特别注意:复制粘贴时的 问题:【正常情况应该不会出现这个问题,然后我把vim后面的空格给删了,然后用打了一个空格,结果就好了,可以新建文件了】

[root@superguy ~]# vim /etc/systemd/system/obfs-server.service
-bash: vim /etc/systemd/system/obfs-server.service: No such file or directory

这里有编译好的软件可直接放到目标位置  obfs-localobfs-server

有可能 443端口被占用了,导致绑定出错,可以换其他端口再重试。

# 查看端口被占用方法

lsof -i:443

客户端:因为是集成插件模式:

1、客户端连接 服务器 端口 就是 443

2、指定 插件为:  obfs-local【有些地方填:simple-obfs】  ;  并配置插件参数 ,如下面的示例。

--plugin-opts "obfs=tls;obfs-host=www.bing.com"

备注:obfs 类型有 tls和http  主要是 服务器 和客户端 类型要统一。

参考教材:

###Plugin mode with shadowsocks
###Add respective item to --plugin and --plugin-opts arg or as value of plugin and plugin_opts in JSON.

### On the client:

ss-local -c config.json --plugin obfs-local --plugin-opts "obfs=http;obfs-host=www.bing.com"
### On the server:

ss-server -c config.json --plugin obfs-server --plugin-opts "obfs=http"
### Standalone mode
### On the client:

obfs-local -s server_ip -p 8139 -l 1984 --obfs http --obfs-host www.bing.com
ss-local -c config.json -s 127.0.0.1 -p 1984 -l 1080
### On the server:

obfs-server -s server_ip -p 8139 --obfs http -r 127.0.0.1:8388
ss-server -c config.json -s 127.0.0.1 -p 8388

七、nginx与shadowsocks共用443端口伪装

1、shadowsocks 转发给 nginx

最近突发奇想把网站改为https,不可避免的遇到了与shadowsocks的443端口冲突问题(443端口不容易被检出)。废了好大劲才发现原来ss的simple-obfs已经带有非ss流量转发功能。

shadowsocks

# HTTP only with plugin mode
ss-server -c config.json --plugin obfs-server --plugin-opts "obfs=http;failover=example.com:80"

# Both HTTP and HTTPS with standalone mode
obfs-server -s server_ip -p 80 --obfs http -r 127.0.0.1:8388 --failover example.com:80
obfs-server -s server_ip -p 443 --obfs tls -r 127.0.0.1:8388 --failover example.com:443

# suppose you have an HTTP webserver (apache/nginx/whatever) listening on localhost:8080 and HTTPS on 8443
# (you probably shouldn't expose these ports)
obfs-server -s server_ip -p 80 --obfs http -r 127.0.0.1:8388 --failover 127.0.0.1:8080
obfs-server -s server_ip -p 443 --obfs tls -r 127.0.0.1:8388 --failover 127.0.0.1:8443

这样便将web流量转发到了8443端口

nginx

user xx xx;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    types_hash_max_size 1024;

    server {
        listen       80;
        server_name  localhost;
        return       301    https://$host$request_uri;  #redir to https
   #     #charset koi8-r;

   #     #access_log  logs/host.access.log  main;

        # redirect server error pages to the static page /50x.html
        #
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   /usr/share/nginx/html;
        #}

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    server {
        listen       8443 ssl http2;
        server_name  localhost;

        ssl_certificate      /etc/letsencrypt/live/cclin.net/fullchain.pem; #managed by Certbot
        ssl_certificate_key  /etc/letsencrypt/live/cclin.net/privkey.pem; #managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location / {
            uwsgi_pass 127.0.0.1:3031;
            include uwsgi_params;
        }

        }
    #   ssl_session_cache    shared:SSL:1m;
    #   ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    }
}

2、利用nginx转发到shadowsocks

下面的方法 可以 ,即访问网站,同时又 ss。 也就是说 simple-obfs 支持 http代理 转发
server {
    listen       80;
     server_name  localhost;
  # server_name  www.huaijiujia.com;
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;

        if ($http_upgrade = "websocket") {
             proxy_pass http://127.0.0.1:8443;
        }
        proxy_http_version 1.1;
        proxy_set_header Upgrade "websocket";
        proxy_set_header Connection "upgrade";
    }

…..

}

下面的 方法 不行,只能访问 网路,但是无法 使用  ss。也就是说 simple-obfs 不支持 tls 代理 转发

server {
    listen   443  default_server;
    server_name  _;
    ssl_certificate     https_cert/huaijiujia_ca_chained.crt;
    ssl_certificate_key https_cert/huaijiujia_private.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
  #  return 404;
   #   return 301 https://www.amazon.com;
      location = / {
        if ($http_upgrade = "websocket") {
             proxy_pass https://127.0.0.1:8443;
        }
        proxy_http_version 1.1;
        proxy_set_header Upgrade "websocket";
        proxy_set_header Connection "upgrade";
    }
   return 301 https://www.amazon.com;
}

因为,安卓手机的功能不完善,不完全支持 simpobfs功能,所以需要重新下个 改进版的。点击下载: Simple-obfuscation-fix


补充:

如果 shadowsocks需要支持 aes-256-gcm加密的话:

For CentOS 7, if you need AEAD ciphers(支持aes-256-gcm加密), you need install libsodium

yum install libsodium python34-pip
pip3 install  git+https://github.com/shadowsocks/shadowsocks.git@master