前者的数据库,深远之bind的模仿实现

日期:2019-10-04编辑作者:美高梅老虎机平台

JavaScript 长远之bind的一成不改变完结

2017/05/26 · JavaScript · bind

原来的书文出处: 冴羽   

前面二个的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,制止转发!
日文出处:www.codemag.com。迎接参加翻译组。

应用程序必要多少。对大多数Web应用程序来讲,数据在服务器端组织和治本,客商端通过网络央求获取。随着浏览器变得进一步有力量,由此可选取在浏览器存储和调整应用程序数据。

正文向您介绍名字为IndexedDB的浏览器端文书档案数据库。使用lndexedDB,你能够经过惯于在劳务器端数据库大约同一的主意开创、读取、更新和删除多量的笔录。请使用本文中可专业的代码版本去感受,完整的源代码能够通过GitHub库找到。

读到本课程的末了时,你将熟稔IndexedDB的基本概念以及哪些贯彻多少个利用IndexedDB实践总体的CRUD操作的模块化JavaScript应用程序。让大家多少亲昵IndexedDB并最初吧。

什么是IndexedDB

日常的话,有二种区别类型的数据库:关系型和文书档案型(也叫做NoSQL或对象)。关周到据库如SQL Server,MySQL,Oracle的多寡存款和储蓄在表中。文书档案数据库如MongoDB,CouchDB,Redis将数据集作为个人对象存款和储蓄。IndexedDB是一个文书档案数据库,它在完全内停放浏览器中的四个沙盒景况中(强制依据(浏览器)同源计谋)。图1来得了IndexedDB的数码,显示了数据库的构造

图片 1

图1:开垦者工具查看叁个object store

整套的IndexedDB API请参见完整文书档案

在线调节和测量检验方案的思念与实践

2015/08/28 · HTML5 · 调试

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

本文的要领不在移动端调节和测量检验上,移动端调节和测量试验无非便是调弄整理页面和调度工具之间存在分离,消除这种分离并成立连结就能够缓慢解决移动端的调节和测验难点。重视演讲的是所见即所得的调试形式下会蒙受的阻挠。

当大家开垦网页,开掘一个模块未有正确地渲染可能空白时,借使调整台有报错,会一直依照报错定位到源码地点上马 debug;即使调整台未有报错,则会基于模块名只怕模块特征的叁个值,通过全局搜索找到那一个模块的职位,然后在调节和测验工具中断点,单步调节和测验,找到难点所在,此时大家也许会如此做:

情形一:

小A同学张开调控台,发现断点调节和测量试验倒霉写代码,于是将削减的源码复制一份保存到地点,格式化,然后将线上能源通过代办工具代理到地头文件。

情形二:

小B同学早早的为团结配了一份本地开垦意况,于是他碰着难题之后,直接去源码中一定错误地方,由于接纳的是预管理语言,所以须求先打包编写翻译之后再在地点预览效果。

情形三:

小C同学的调治将养格局是小A和小B的总结版本,将线上的能源代理到地面 build 目录文件,在 src 目录下修改以往编写翻译打包到 build,然后预览。

即利用了 https 也绝不通过 query strings 传敏感数据

2017/10/16 · 基础能力 · HTTPS

本文由 伯乐在线 - xiaoheike 翻译,艾凌风 校稿。未经许可,禁绝转载!
加泰罗尼亚语出处:HttpWatch。迎接参预翻译组。

劳动器端的 log 将公开记下完整 url;浏览器上的拜候历史也会公然记下完整 url;Referrer headers 里也忠实记下全体 url,然后在外人家的 谷歌(Google)Analytics 上显得。

咱俩平日听到的多个常见难点是:“URL 中的参数是或不是足以高枕而卧地传递到平安网站?”这些标题时常出现在顾客看了 HttpWatch 捕获的 HTTPS 央浼后,想清楚还应该有何人能够看看这一个数据。

 

举例说,假使在三个询问中,使用如下安全的 URL 传递密码字符串:

HttpWatch 能够显得安全诉求的剧情,因为它与浏览器集成,因而它亦可在 HTTPS 请求的 SSL 连接对数据加密之前查看数据。图片 2

假若你利用网络嗅探器查看,举例 Network Monitor,对于同多个呼吁,你只好够查阅加密随后的数码。在多少包追踪中并未可见的网站,题目或内容:

图片 3

你能够信任 HTTPS 央求是高枕而卧的,只要:

  • 未忽略任何SSL证书警告
  • Web 服务器用于运维 SSL 连接的私钥在 Web 服务器自身之外不可用。

由此,在网络范围,URL 参数是安全的,不过还会有一对任何依照 URL 泄漏数据的艺术:

  1. URL 存款和储蓄在 Web 服务器日志中–平常每一个需要的全体 URL 都被存放在在服务器日志中。那象征 URL 中的任何敏感数据(比方密码)会以公开形式保留在服务器上。以下是选择查询字符串通过 HTTPS 发送密码时存款和储蓄在 httpwatch.com 服务器日志中的条目款项: **二零零六-02-20 10:18:27 W3SVC4326 WWW 208.101.31.210 GET /Default.htm password=mypassword 443 … 平日感觉纵然是在服务器上,存款和储蓄明文密码一贯都不是好主张 2.URLs are stored in the browser history – browsers save URL parameters in their history even if the secure pages themselves are not cached. Here’s the IE history displaying the URL parameter:
  2. URL 存储在浏览器历史记录中–固然安全网页自个儿未缓存,浏览器也会将 URL 参数保存在其历史记录中。以下是 IE 的历史记录,展现了 URL 的呼吁参数:图片 4

只要客商成立书签,查询字符串参数也将被积存。

  1. URLReferrer 须求头中被传送–假若一个有惊无险网页使用财富,比方 javascript,图片可能深入分析服务,URL 将通过 Referrer 恳求头传递到每三个内置对象。有时,查询字符串参数大概被传送并存放在第三方站点。在 HttpWatch 中,你可以观望大家的密码字符串正被发送到 Google Analytics图片 5

结论

消除那几个题材亟需两步:

  • 除非在相对少不了的状态下传递敏感数据。一旦顾客被证实,最棒使用具备有限生命周期的会话 ID 来标志它们。

行使会话层级的 cookies 传递音讯的亮点是:

  • 它们不会蕴藏在浏览器历史记录中或磁盘上
  • 它们平日不存款和储蓄在服务器日志中
  • 它们不会传递到嵌入式能源,比如图片或 JavaScript
  • 它们仅适用于伏乞它们的域和路线

以下是我们的在线商场中,用于识别客商的 ASP.NET 会话 cookie 示例:

图片 6

请注意,cookie 被限制在域 store.httpwatch.com,并且在浏览器会话结束时过期(即不会积累到磁盘)。

你当然能够通过 HTTPS 传递查询字符串,不过绝不在只怕出现安全难点的情景下利用。举个例子,你能够安全的利用它们显示部分数字依然项目,像 accountview 或者 printpage,可是不要使用它们传递密码,银行卡号码可能别的不该精通的音信。

1 赞 收藏 评论

主流浏览器图片反防盗链方法计算

2018/04/24 · HTML5 · 防盗链

初稿出处: Myths   

bind

一句话介绍 bind:

bind() 方法会创设叁个新函数。当那一个新函数被调用时,bind() 的率先个参数将作为它运转时的 this,之后的一体系参数将会在传递的实参前传出作为它的参数。(来自于 MDN )

经过大家得以率先得出 bind 函数的两特性状:

  1. 重回贰个函数
  2. 可以流传参数

设计标准

IndexedDB的架构很像在部分流行的劳动器端NOSQL数据库完成中的设计规范类型。面向对象数据经过object stores(对象客栈)举行长久化,全体操作基于诉求同不时间在事情限制内执行。事件生命周期使您能够决定数据库的配备,错误通过荒谬冒泡来使用API管理。

☞ 代理调节和测量检验的烦躁

而对此比较复杂的线上蒙受,代理也会遇上相当多障碍,举个例子:

线上财富 combo

出现错误的脚本地址为  ,它对应着 a.js,b.js,c.js 八个剧本文件,假设大家应用 Fiddler/查理那样的卓越代理工科具调节和测量试验代码,就必需给这一个工具编写插件,大概在轮换配置内部加一批推断大概正则,开支高,门槛高。

线上代码压缩

打包压缩,那是上线此前的必经流程。由于大家在包装的环节中并从未思量为代码增多sourceMap,而线上事先对应 index-min.jsindex.js 也因为安全地点的因由给干掉了,那给大家调节和测验代码产生了天翻地覆的不低价。

代码重视比较多,拉代替码难题

多多时候,大家的页面信任了多少个 asserts 资源,而那几个资源各自布满在多个商旅里面,以至散布在分歧的宣布平台上,为了能够在源码上清晰的调和代码,大家只可以将兼具的财富下载到本地,时期假设存在下载代码的权能难点,整个调节和测量试验进程就慢下来,那是卓殊不能够忍受的事体。比如某系统创设的页面,页面上的模块都是以酒店为维度区分的,三个页面或许对应了5-48个旅社,下载代码实为劳动。

最吓人的调解是,当地未有对应的测验蒙受、代理工科具又不满意大家的要求,然后就只能, 编辑代码->打包压缩->提交代码->查看效果->编辑代码->... ,倘使您的品类成本是这种形式,请停下来,考虑调节和测验优化方案,正所谓磨刀不误砍柴工。

有关小编:xiaoheike

图片 7

简要介绍还没来得及写 :) 个人主页 · 作者的作品 · 10 ·      

图片 8

前言

还记得在此之前写的十三分无聊的插件,前一段时间由于豆瓣读书扩张了防盗链战术使得大家鞭长莫及直接援用他们的图形,使得作者这几个小插件不能够工作。本感觉是一个很简短的标题,然则没悟出那么些符合规律正是让小编改了五肆回才改好,能够视为特别的蠢了。总计一下协和犯傻的由来,依旧出于自己懒得去深刻钻研,谷歌(Google)百度了难点就直接把方案拿来用了,一曝十寒盲目从众,化解了表面的标题而并未有深切的总计。当然,从另外一个地点讲,俺也是起先领悟到了前面二个技士面前境遇要协作各样浏览器的急需时头有多大了。

回来函数的模仿完成

从第三个特征开首,大家举例:

var foo = { value: 1 }; function bar() { console.log(this.value); } // 再次来到了三个函数 var bindFoo = bar.bind(foo); bindFoo(); // 1

1
2
3
4
5
6
7
8
9
10
11
12
var foo = {
    value: 1
};
 
function bar() {
    console.log(this.value);
}
 
// 返回了一个函数
var bindFoo = bar.bind(foo);
 
bindFoo(); // 1

至于钦定 this 的针对,大家能够运用 call 可能 apply 完毕,关于 call 和 apply 的效仿完成,能够查阅《JavaScript深刻之call和apply的模仿达成》。大家来写第一版的代码:

// 第一版 Function.prototype.bind2 = function (context) { var self = this; return function () { self.apply(context); } }

1
2
3
4
5
6
7
8
// 第一版
Function.prototype.bind2 = function (context) {
    var self = this;
    return function () {
        self.apply(context);
    }
 
}

目的酒馆

object store是IndexedDB数据库的功底。若是您利用过关周详据库,平日可以将object store等价于八个数码库表。Object stores包含贰个或多少个目录,在store中坚守一对键/值操作,那提供一种高效牢固数据的点子。

当你安顿三个object store,你必得为store选择一个键。键在store中可以以“in-line”或“out-of-line”的办法存在。in-line键通过在数码对象上援用path来保险它在object store的独一性。为了表明那一点,想想多少个富含电子邮件地址属性Person对象。您可以布署你的store使用in-line键emailAddress,它能保险store(持久化对象中的数据)的独一性。别的,out-of-line键通过独立于数据的值识别独一性。在这种情景下,你能够把out-of-line键比作三个莫西干发型值,它(整数值)在关周详据库中充作记录的主键。

图1展示了职分数据保存在任务的object store,它选择in-line键。在那么些案例中,键对应于对象的ID值。

☞ 开启懒人调节和测量试验方式

当见到线上冒出难题(恐怕是其余同学负担页面的难点),脑中浮出这样的景色:

复制代码 作者:"嘿,线上有难点呀!笔者要调治代码!" 计算机:"好的,主人。请问是哪些页面?"(弹出浮层) 笔者:浮层中输入U瑞虎L。 计算机:"请问是哪位地方出标题了?" 笔者:(指着计算机)"模块A和模块B。" 计算机:正在下载A、B财富...正在将上线A、B映射到地头...自动展开A、B对应文件夹 小编:编辑代码,然后实时预览效果。

1
2
3
4
5
6
7
8
复制代码
  我:"嘿,线上有问题啦!我要调试代码!"
电脑:"好的,主人。请问是哪个页面?"(弹出浮层)
  我:浮层中输入URL。
电脑:"请问是哪个地方出问题了?"
  我:(指着电脑)"模块A和模块B。"
电脑:正在下载A、B资源...正在将上线A、B映射到本地...自动打开A、B对应文件夹
  我:编辑代码,然后实时预览效果。

在此处我们供给消除那样多少个难题

  • 将页面临应的有着货仓/财富罗列在顾客如今
  • 下载财富的权力提醒和权力管理
  • 线上能源解 combo,然后映射到地头

自然调节和测量试验之后,能够还应该有一个操作:

本人:"哈,已经修复了,帮本身付诸代码~" 计算机:正在diff代码...收到确认提交随机信号,提交到预发景况...收到已经预览实信号...正在公布代码...收到线上回归连续信号...流程甘休

1
2
我:"哈,已经修复了,帮我提交代码~"
电脑:正在diff代码...收到确认提交信号,提交到预发环境...收到已经预览信号...正在发布代码...收到线上回归信号...流程结束

除却 debug 代码,大家需求做的就只是用肉眼看效果是或不是ok,整个流程优化下来,体验是十分赞的!

问题

主题材料很轻便,正是本人梦想在温馨的页面里用`来引用其他网站的一张图片,但是他的网站设置了防盗链的策略,会在后台判断请求的Referrer属性是不是来自于一个非本域名的网站,如果来源不是本域名就返回403 forbidden`。小编的指标就是用最实惠的艺术使得本身的页面可以不受他的防盗链计策的影响。

传参的效仿实现

接下去看第二点,能够流传参数。那个就有一些令人费解了,小编在 bind 的时候,是还是不是足以传参呢?小编在进行 bind 重返的函数的时候,行还是不行传参呢?让咱们看个例证:

var foo = { value: 1 }; function bar(name, age) { console.log(this.value); console.log(name); console.log(age); } var bindFoo = bar.bind(foo, 'daisy'); bindFoo('18'); // 1 // daisy // 18

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var foo = {
    value: 1
};
 
function bar(name, age) {
    console.log(this.value);
    console.log(name);
    console.log(age);
 
}
 
var bindFoo = bar.bind(foo, 'daisy');
bindFoo('18');
// 1
// daisy
// 18

函数必要传 name 和 age 多个参数,竟然还是可以在 bind 的时候,只传三个name,在实施回来的函数的时候,再传另二个参数 age!

这可怎么办?不急,大家用 arguments 举行管理:

// 第二版 Function.prototype.bind2 = function (context) { var self = this; // 获取bind2函数从第一个参数到最终贰个参数 var args = Array.prototype.slice.call(arguments, 1); return function () { // 那年的arguments是指bind再次回到的函数字传送入的参数 var bindArgs = Array.prototype.slice.call(arguments); self.apply(context, args.concat(bindArgs)); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 第二版
Function.prototype.bind2 = function (context) {
 
    var self = this;
    // 获取bind2函数从第二个参数到最后一个参数
    var args = Array.prototype.slice.call(arguments, 1);
 
    return function () {
        // 这个时候的arguments是指bind返回的函数传入的参数
        var bindArgs = Array.prototype.slice.call(arguments);
        self.apply(context, args.concat(bindArgs));
    }
 
}

基于事务

不一致于一些守旧的关全面据库的落实,每四个对数据库操作是在二个事情的内外文中试行的。事务限制贰回影响三个或四个object stores,你通过传播贰个object store名字的数组到开创专门的职业限制的函数来定义。

创建职业的第二个参数是职业方式。当呼吁二个事务时,必得调节是比照只读依然读写格局恳求访问。事务是财富密集型的,所以只要您无需退换data store中的数据,你只要求以只读方式对object stores会集实行呼吁访谈。

清单2演示了怎么样运用格外的形式开创一个事情,并在那片小说的 Implementing Database-Specific Code 部分开展了详尽座谈。

☞ 消除代理遭受的主题材料

上边大家关系了多个难题,日常付出碰到最胃痛的一个是 combo ,曾经大家页面上的代码加三个?_xxx  参数就可以一直初阶调节和测量检验情势,那是因为程序的进口独有五个,何况具备脚本的信赖性也卷入到三个誉为 deps.js  文件中,加上调试参数之后,能够将本来 combo 加载的文件:  ,遵照非 combo 的艺术加载:

1
2
3
http://example.com/path/a.js
http://example.com/path/b.js
http://example.com/path/c.js

上边包车型大巴代码能够轻巧地代理到地面,可是部分系统生成的代码并未 deps.js  文件,它是将脚本间接出口到页面上:

<script src=";

1
<script src="http://example.com/path/??a-min.js,b-min.js,c-min.js"></script>

☞ 解决 combo 问题

那儿通过 Fiddler/Charles工具比较难满足急需,对于那么些难点有三个管理方案:

1). 浏览器乞请全体代理到地面包车型客车四个劳动

先是写一个本地服务:

JavaScript

var http = require('http'); // npm i http-proxy --save var httpProxy = require('http-proxy'); var proxy = httpProxy.createProxyServer({}); var server = http.createServer(function(req, res) { console.log(req.url); if(req.url.indexOf("??") > -1){ // combo能源让 3400 端口的劳务管理proxy.web(req, res, { target: '' }); } else { // 直接重临 proxy.web(req, res, { target: req.url }); } }).listen(3399, function(){ console.log("在端口 3399 监听浏览器乞求"); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var http = require('http');
// npm i http-proxy --save
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
 
var server = http.createServer(function(req, res) {
  console.log(req.url);
  if(req.url.indexOf("??") > -1){
    // combo资源让 3400 端口的服务处理
    proxy.web(req, res, { target: 'http://127.0.0.1:3400' });
  } else {
    // 直接返回
    proxy.web(req, res, { target: req.url });
  }
}).listen(3399, function(){
    console.log("在端口 3399 监听浏览器请求");
});

代码的野趣是,利用 http-proxy 这些 npm 包,代理浏览器的呼吁,浏览器上使用 switchSharp 设置本地代理为  ,当呼吁过来,先判定url,假若 url 中蕴藏了 ?? 则将其用作 combo 能源管理,代理给本地的另一个服务  ,这些服务接受央浼后会将 combo 内容分解成八个,全部伸手完事后再吐出来。

2). 使用本地服务诉求 html 代码,替换 html 代码内容

使用强制手腕(源码替换)将代码解 combo,比如源码页面为:

前者的数据库,深远之bind的模仿实现。<!-- html code --> <script src="; <!-- html code -->

1
2
3
<!-- html code -->
<script src="http://example.com/path/??a-min.js,b-min.js,c-min.js"></script>
<!-- html code -->

运用本地服务央求这么些url,然后转变到:

<!-- html code --> <script src="; <script src="; <script src="; <!-- html code -->

1
2
3
4
5
<!-- html code -->
<script src="http://example.com/path/a.js"></script>
<script src="http://example.com/path/b.js"></script>
<script src="http://example.com/path/c.js"></script>
<!-- html code -->

兑现那些操作的代码:

JavaScript

var http = require('http'); // npm i request --save; var request = require('request'); http.createServer(function(req, res){ var path = req.url.slice(req.url.indexOf("path=") + 5); console.log(path); if(!path) { res.write("path is empty"); res.end(); return; } request(path, function (error, response, body) { if (!error && response.statusCode == 200) { console.log(body); // 代码替换 body = body.replace('<script src=";', '<script src=" <script src=" <script src=";' ); res.write(body); res.end(); } }); }).listen(3399, function(){ console.log("listening on port 3399"); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var http = require('http');
// npm i request --save;
var request = require('request');
http.createServer(function(req, res){
    var path = req.url.slice(req.url.indexOf("path=") + 5);
    console.log(path);
    if(!path) {
        res.write("path is empty");
        res.end();
        return;
    }
    request(path, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body);
            // 代码替换
            body = body.replace('<script src="http://example.com/path/??a-min.js,b-min.js,c-min.js"></script>',
                '<script src="http://example.com/path/a.js"></script>
                <script src="http://example.com/path/b.js"></script>
                <script src="http://example.com/path/c.js"></script>'
            );
            res.write(body);
            res.end();
        }
    });
}).listen(3399, function(){
    console.log("listening on port 3399");
});

举例央浼  ,就可以得到天猫首页的源码,然后对得到的代码做替换。

☞ 化解代码压缩难点

对于这些标题,建议在线上放两份源码,一份是缩减源码,一份是未压缩源码,当页面 url 存在 debug 参数的时候,重回未压缩版本,符合规律重临压缩版本。当然,也足以接纳上述方式管理难题。

唯独,更合理的方法应该是 sourceMap,前端未有地下,压缩代码只是扩充了 骇客 的抨击费用,并无妨碍有技巧的 黑客借系统漏洞入侵。所以可感觉源码提供一份 sourceMap 文件。

JavaScript

var gulp = require('gulp'); var sourcemaps = require('gulp-sourcemaps'); gulp.task('javascript', function() { gulp.src('src/**/*.js') .pipe(sourcemaps.init()) //.pipe(xx()) .pipe(sourcemaps.write()) .pipe(gulp.dest('dist')); });

1
2
3
4
5
6
7
8
9
10
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
 
gulp.task('javascript', function() {
  gulp.src('src/**/*.js')
    .pipe(sourcemaps.init())
      //.pipe(xx())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('dist'));
});

至于 sourceMap 的 gulp 插件配置,详细的情况能够戳这里。不止是 JavaScript,CSS 也许有 source maps,这一个音讯能够在 Chrome 调节台的装置选项中看到:

图片 9

☞ 代码的拉取

要是二个类型独有你精通什么样修改,那那几个类其余技巧设计就有一点不好了,为了让大家都能管理你项目中的难点,绝对要索要叁个简短的方式为开垦者火速搭建测量检验情况,文书档案是一只,假设有个一键操作的通令,那就更棒了!

# 运行脚本 start: createFile getMod getPage # 创设目录 createFile: @[ -d module ] || mkdir module @[ -d page ] || mkdir page # 拉取模块客栈,这里有几13个,比较费时,请耐心等待... getMod: cd module; for i in $(MODS); do [ -d $(MODPATH)$$i ] || git clone $(MODPATH)$$i; git co -b master; git co -b $(MODSV); done # 拉取页面仓库,tbindex getPage: cd page; @[ -d tbindex ] || git clone $(PAGEPATH)$PAGE;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 启动脚本
start: createFile getMod getPage
 
# 创建目录
createFile:
  @[ -d module ] || mkdir module
  @[ -d page ] || mkdir page
 
# 拉取模块仓库,这里有几十个,比较费时,请耐心等待...
getMod:
  cd module;
  for i in $(MODS); do
    [ -d $(MODPATH)$$i ] || git clone $(MODPATH)$$i;
    git co -b master;
    git co -b $(MODSV);
  done
 
# 拉取页面仓库,tbindex
getPage:
  cd page;
  @[ -d tbindex ] || git clone $(PAGEPATH)$PAGE;

 

地方是贰个 MakeFile 的有的代码,效用是创制开采目录,拉取分支音信,然后伊始服务器,打开浏览器,使用 IDE 张开目录,万事就绪,只等主人敲代码。

一切工艺流程就一两分钟,实现支付此前全部的策画干活。那么些本子不仅是给自身行使,假如其余人也急需加入开发,贰个下令就能够让参加者踏入开辟情势,加上文书档案表达,省却了累累交流开支。

焚薮而田方案

本文由澳门美高梅老虎机平台发布于美高梅老虎机平台,转载请注明出处:前者的数据库,深远之bind的模仿实现

关键词:

10个HTML5摄影及水墨画设计工具,从本质认知Jav

十二个HTML5摄影及油画设计工具 2011/03/26 · HTML5 · 来源:smashinghub    · HTML5 Mr. Doob’s Harmony 特别切合随手绘制勾勒...

详细>>