首页
Search
1
解决visual studio code (vscode)安装时没有选择安装路径问题
138 阅读
2
Linux 下 Bash 脚本 bad interpreter 报错的解决方法
131 阅读
3
Arch Linux 下解决 KDE Plasma Discover 的 Unable to load applications 错误
107 阅读
4
如何在 Clash for Windows 上配置服务
77 阅读
5
Uniapp如何引入自定义样式文件
75 阅读
clash
服务器
javascript
全部
游戏资讯
登录
Search
加速器之家
累计撰写
1,061
篇文章
累计收到
0
条评论
首页
栏目
clash
服务器
javascript
全部
游戏资讯
页面
搜索到
624
篇与
的结果
2024-10-21
https的研究与总结
为了保证用户数据的安全性、避免中间运营商的劫持,部署 https 已成当务之急。https 早已不是锦上添加的可有可无项,它已经逐渐成为 WEB 服务的标配。那么什么是 https 呢,https 与 http 的区别在哪儿,我们作为前端在部署 https 时应该注意什么呢? 1. http 与 https 的区别 # 我们传统使用的 http 是 http1.0,是基于 TCP/IP 的应用层协议,浏览器的每次请求都需要与服务器建立一个 TCP 连接,服务器完成请求处理后立即断开 TCP 连接,服务器不再跟踪之前的请求。这种方式优点是: 通信开销小,简单快速,传输成本低; 使用灵活,允许传输任意类型或数据格式的对象,传输的类型由 Content-Type 标记 但 http 还有着更明显的缺点,导致使用 http 协议的不安全: 使用明文(不加密)的方式进行传输,内容容易被窃听和获取; 不验证通信方的身份,有可能遭遇伪装; 无法验证明文的完整性,有可能被篡改 正是因为 http 存在着不足的地方,才需要一个更安全的协议来保证数据在传输过程中安全。https=http+加密+认证+完整性保护,https 就是 http 的安全升级版。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密。https 报文中的任何东西都被加密,包括所有报头和荷载。一个攻击者所能知道的只是两者之前有一个连接而已。 2. 运营商劫持 # 在我们通常使用的 http 协议里,信息都是使用明文的方式传输的,那么中间的运营商就有可能在信息上做手脚。运营商劫持主要有三种方式: DNS 劫持:又叫 DNS 重定向攻击,将用户到想到非预期网站的行为,主要是通过修改用户的 DNS 解析结果实现 url 劫持: 302 跳转劫持,将用户 url 重定向到非目标网站 修改 url 参数,比如在 url 里添加流量渠道标识或者页面参数 网页内容篡改 直接在网页中插入 js 在网页中嵌入 iframe 万一在遇到运营商劫持的情况时,有哪些应对方案呢 投诉增值业务部门进而投诉工信部 绕过运营商的 localDNS,使用公共的 DNS 抛弃域名访问方式,直接通过 IP 访问 https:https 只能解决连接劫持,无法解决 DNS 劫持 3. SPDY # SPDY 是 google 开发的基于传输控制协议(TCP)的应用层协议,SPDY 协议旨在通过压缩、多路复用和优先级来缩短网页的加载时间和提高安全性。(SPDY 是 speedy 的昵音,意为更快)SPDY 与 http 的关系:SPDY 协议只在性能上对 http 做了很大的优化,其核心思想是尽量减少连接个数,而对于 http 的语义并没有做太大的修改。具体来说是,SPDY 使用了 HTTP 的方法和页眉,但是删除了一些头并重写了 HTTP 中管理连接和数据转移格式的部分,所以基本上是兼容 HTTP 的。 HTTP 的 GET 和 POST 消息格式保持不变,即现有的所有服务端应用均不用做任何修改。SPDY 协议的优点: 多路复用 请求优化: 在一个连接内可以有多个请求,通过复用在单个 TCP 连接上的多次请求,而非为每个请求单独开放连接 支持服务器推送技术: 服务器可以主动向客户端发起通信向客户端推送数据,这种预加载可以使用户一直保持一个快速的网络。 压缩了 http 头: 舍弃掉了不必要的头信息,经过压缩之后可以节省多余数据传输所带来的等待时间和带宽 强制使用 SSL 传输协议: Web 未来的发展方向必定是安全的网络连接,全部请求 SSL 加密后,信息传输更加安全。 4. 在迁移到 https 的过程中,我们应该做些什么 # 在 https 的页面里,是不能有 http 链接存在的,在 chrome 下依然会请求服务器,但会在控制台给出警告;在 firefox 下直接拒绝请求,可能会知道页面混乱或报错。因此,在 https 的页面里,我们要确保所有的内部链接全部指向 https,确保已经在页面到页面级别制定了新的 https 网址。具体的操作是: 所有的链接指向 https,或者不明确协议,用//开头,则请求资源的协议与页面相同 如果页面中依然还有 http 的链接,可以在头部添加此 meta 头,自动将 http 资源替换成 https 请求: 所有的静态资源(js, css ,img 等)均需上传至 CDN 域名下:img1.gting.com 和 mat1.gtimg.com 我们尽量保证 https 页面里不含有 http 的链接,但是人工检查难免有疏漏的,因此写了一个 js 脚本用来检测页面中 http 连接的数量:(function () { var tags = ["link", "script", "img", "audo", "video", "frame"], // 遍历的资源 host_protocol = window.location.protocol.replace(":", ""), // 当前页面的协议 flag = true; // 是否打开上传 if (host_protocol == "https" && flag) { var a = document.createElement("a"), result = ""; for (var i = 0, len = tags.length; i < len; i++) { var item = document.getElementsByTagName(tags[i]), num = 0; for (var j = 0, t = item.length; j < t; j++) { var c = item[j]; var url = c.getAttribute("href") || c.getAttribute("src") || c.href || c.src; if (url) { a.href = url; var protocol = a.protocol.replace(":", ""); // var protocol = url.substr(0, 5); if (protocol == "http") { num++; } } } num && (result += tags[i] + "=" + num + "|"); } result = result.substring(0, result.length - 1); // console.log( result ); // console.log( encodeURIComponent(result) ); var img = new Image(); img.src = "http://www.qq.com/s.gif?q=" + encodeURIComponent(result); img.onload = img.onerror = function () { img = null; }; } })(); 这个脚本能在页面加载完成后,扫描页面中的资源,检测其链接是否为 http 类型,且只在 https 的页面中,开关打开的情况下才运行,统计各个资源里 http 的个数。不过更详细的信息还不太好获取到,比如:链接为 http 类型的资源在页面中的第几行,ajax 请求的链接等信息。 5. http2 展望 # HTTP/2 主要基于 SPDY 协议,不过还是有区别的, http/2 支持明文 http 传输,而 SPDY 强制使用 https。 HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能。http2 特点是: 多路复用:与 SPDY 类似,这样,就省掉了多次建立连接的时间,这个时间对 TLS 尤其明显,因为 TLS 连接费时间 加速 TLS 交付:HTTP/2 只需一次耗时的 TLS 握手,并且通过一个连接上的多路利用实现最佳性能。HTTP/2 还会压缩首部数据 简化 web 应用,适合内容混杂的页面: 用 HTTP/2 可以让 Web 开发者省很多事,因为不用再做那些针对 HTTP/1.x 的优化工作了 更安全: 通过减少 TLS 的性能损失,可以让更多应用使用 TLS,从而让用户信息更安全 那么在未来的 http2 下,我们前端需要做些什么呢? 减少 http 请求不一定提升性能: 减少 http 请求的前提是资源的合并,导致单个文件的体积变大,根据测试表明,在 http2 的环境下,合并为一个大文件的加载时间反而会比不合并更长 压缩仍然需要:毕竟获取一个小文件的时间比大文件更短,http2 并不会帮你自动压缩文件。HTTP/2 目的之一,就在于想把开发环境与生产环境的部署尽量保持一致,减少因为打包合并而产生一些不必要的麻烦 未来将更专注与页面本身而非性能:http2 从页面加载速度,资源请求,安全性等做很多的工作,让我们更加专注于页面功能上的实现。 如果还有什么不足,欢迎指出批评,谢谢。
2024年10月21日
8 阅读
0 评论
0 点赞
2024-10-21
对移动端h5项目的一点总结
到现在也做了不少的h5,遇到了不少的坑,也对曾经的经验教训总结一下。主要做过的项目有: 智图派-腾讯财经 腾讯财经年终策划 NBA全明星推广 答题闹元宵 快报送Q币 看见淤青有多难 奥运暗黑室 腾讯嘉年华 超级名人赛 快报 摇一摇 每个项目都有这样那样的难点,现在都分别总结一下。 1. 智图派-腾讯财经 # 项目地址为: http://finance.qq.com/zt2015/nzcehua1/zhitupai.htm。这个项目的亮点是进入到首页后,就是根据当前的时间,每一位都滚动到对应的数字。我实现的思路是: 计算当前时间与设定好的时间节点之间的时间差; 将时间差转换为数组; 根据数组的位数,给每一位都填充上0-9这10个数字; 使用CSS3的transition和transform,获取每个数字的高度和当前位置的数字,计算出滚动的距离。 CSS:.timer .t{ font-size: 3rem; line-height: 3rem; border: 2px solid #a2a2a2; height: 62px; overflow: hidden; display: inline-block; margin-right: 4px; } .timer .t div{ -webkit-transition: -webkit-transform 800ms cubic-bezier(0.42, 0, 0.58, 1) 300ms; -ms-transition: transform 800ms cubic-bezier(0.42, 0, 0.58, 1) 300ms; transition: transform 800ms cubic-bezier(0.42, 0, 0.58, 1) 300ms; } .timer .t em{ padding: 7px 12px; display: block; font-style: normal; } HTML: JS:(function(){ var left = ''; function set(){ var point = 1451577600, // 节点 now = parseInt( Date.now()/1000 ); // 当前时间 left = now-point; left = (left+'').split(''); // 将数字转换为数组 var html = ''; for(var i=0, len=left.length; i SHAKE_THRESHOLD) { // 摇一摇发生的事件 // ... } last_x = x; last_y = y; last_z = z; } } init(); })(); 总结 # 以后还会有更多的移动项目等待我们,也还会遇到各种各样的问题。每次遇到问题时,就总结一下,涨一次教训。
2024年10月21日
5 阅读
0 评论
0 点赞
2024-10-21
小型网站如何生成订单号
在流量不太高的网站里,如何生成订单号呢,网上肯定也有很多成熟的方案,这里也是提供下自己的思路。订单号如何生成是要根据当前业务的需求才实现的,所有的东西都是不断进化的,你不可能起步就按照京东淘宝的标准来,根据实际情况实际分析就可以了,脱离需求谈实现都是耍流氓。下面也仅仅是对交易量不高的网站提供的一点思路。 20220310 新增 # 以前没有高并发的经验(其实现在也没有),随手写了点订单号生成的逻辑。不过逻辑确实有问题,任何依赖随机数的订单号系统,都是耍流氓。既然是随机数,就有可能产生冲突;依赖时间的,就得考虑时钟回拨的问题;分布式的,就得考虑多台机器之间订单号的互斥性;有自增类型的,就得考虑怎么维护这个自增的数字,是统一在 redis 中维护,还是在某个时间段内自增,等等。高并发下,生成订单号的特点是: 唯一性; 不可推测性; 效率高; 现在有很多经过大厂验证过的方案,如雪花算法、UUID、数据库自增、Redis、美团 Leaf 等,都是经得起考验的订单号生成算法。在要求不高的场景下,如不限制订单号的长度、没有分布式、不考虑时钟回拨等,那么时间戳 + (自增 | 随机数)就足够了。如 jQuery 中的 jsonp 的 callback 名称,就是时间戳 + 随机数的方式生成的。每个客户端都是独立的,也不用考虑多个客户端冲突的问题。其次是时间戳 + 自增的方式,这个自增可以限制在单位时间内自增,时间戳一改变,则自增数字重置。const create = () => { let lasttime = ''; // 上一个时间戳 let num = 0; // 自增的数字 return () => { const now = Date.now().toString(36); if (now === lasttime) { // 若当前时间戳与刚才相同,则直接自增 num++; const inc = `0${num.toString(36)}`.slice(-2); return `${now}${inc}`; } // 若当前时间戳发生变化,则自增数字重置 lasttime = now; num = 0; return `${now}00`; }; }; const uuid = create(); // 使用: for (let i = 0; i < 1000; i++) { console.log(uuid()); // l0kd0nep1w } 原文 # 思路: 日期+自增数字 : ,如果你的网站每天的交易量很小,那么使用日期+自增数字的方式就完全足够使用了; 日期+随机数 : 如果自增数字会暴露每天的交易量,那么日期+随机数也是一种比较好的方式。但是每次生成随机数后,都要检测当前随机数是否已经使用,如果已经使用还需要重新生成; 下面的这种方式是我目前在使用的,生成的订单号也会比较长,订单号由三部分组成: 秒级的时间,当然你也可以使用毫秒级的时间; 随机数+uid 的后 6 位: (md5(毫秒级级时间戳)+uid)的后 6 位; 1000-9999 之间的随机数 最终生成的订单号是这样的: 2016120108580747d4d10790 。 20161201085807 是精确到秒级的时间,47d4d1 是 md5+uid,0790 是随机数。这样的一种订单号生成规则,在并发量不太高的情况下时: 多个用户几乎同时提交订单时,不会造成生成重复的订单号,因为每个订单号都是与 uid 相关联的; 同一个用户若一秒内提交的订单不多的话,第 2 步和第 3 步也是能满足订单号生成的,不过会有一定的风险。 不过这种订单号生成方式会暴露用户的 uid,我们可以使用某些转换方式,将 uid 隐藏。这也是我提供的一种思路而已,欢迎大家参考。
2024年10月21日
4 阅读
0 评论
0 点赞
2024-10-21
什么是window.chrome
在以前我们需要检测当前浏览器是否是chrome时,通常我们是使用UA进行检测的:var isChrome = navigator.userAgent.toLowerCase().match(/chrome/) != null; console.log( isChrome ); 不过现在又有新的方法可以检测是否是chrome浏览器了。在chrome浏览器里有一个全局变量window.chrome,我们也直接使用这个全局变量来进行判断:if( window.chrome ){ alert('此浏览器为chrome浏览器'); } 在window.chrome的全局变量里,有app, csi, loadTimes, runtime, webstore这些属性和方法,不过网上关于window.chrome这个变量的资料还是很少。window.chrome.app和window.chrome.webstore可能跟chrome扩展程序和网上应用商店有关系。 1. window.chrome.csi # window.chrome.csi是一个方法,执行 window.chrome.csi() 后会获得3个属性(不同版本的chrome里也会有tran属性):console.log( window.chrome.csi() ); { onloadT:1481031352403 pageT:70382.456 startE:1481031350604 tran:15 } startE : 页面开始加载时的毫秒时间戳(1481010621721); onloadT : 页面加载完后的毫秒时间戳(1481010626707); pageT : 自页面开始加载到现在的毫秒时间(5695686.301); tran : 目前不知该字段是什么含义 因此onloadT减去startE就能获取到页面的加载时间。 2. window.chrome.loadTimes # window.chrome.loadTimes也是一个方法,执行后更多关于页面加载的信息:console.log( window.chrome.loadTimes() ); { commitLoadTime:1481032100.719 connectionInfo:"http/1.1" finishDocumentLoadTime:1481032101.293 finishLoadTime:1481032101.439 firstPaintAfterLoadTime:0 firstPaintTime:1481032101.013 navigationType:"Reload" npnNegotiatedProtocol:"http/1.1" requestTime:1481032100.595 startLoadTime:1481032100.595 wasAlternateProtocolAvailable:false wasFetchedViaSpdy:false wasNpnNegotiated:true } 目前这里面我也有几个字段的含义不太明白,还望各位网友指点:跟时间有关的属性(单位全部为秒): requestTime : 请求时间; startLoadTime : 开始加载时间; commitLoadTime firstPaintTime : 首次渲染时间 firstPaintAfterLoadTime finishDocumentLoadTime : 文档首次加载完成时间 finishLoadTime : 页面加载完成时间 其他属性: connectionInfo : 连接协议(主要有: http/1.1,h2, quic/1+spdy/3等) navigationType : 打开类型(Reload:刷新页面, Other:首次打开页面) npnNegotiatedProtocol : 不明白含义,与connectionInfo保持一致 wasFetchedViaSpdy : 是否通过spdy协议传输 除了通过开发者工具查看加载时间外,也可以通过js直接打印各个时间。 3. 总结 # 在上面讲述的两个属性里,有两个属性表示的含义是相同的,不过只是时间单位不同而已:var csi = window.chrome.csi(), loadTimes = window.chrome.loadTimes(); csi.startE == loadTimes.startLoadTime*1000; csi.onloadT == loadTimes.finishDocumentLoadTime*1000; 在多次执行window.chrome.csi()和window.chrome.loadTimes()后发现,除了pageT属性是表示当前页面打开的时间外,其他的属性都不会变的。因此只要这两个方法在页面加载完成后执行,不论什么时候执行,都是能获取到准确的数据的。通过这个特性,我们就可以写一个方法来打印我们想要的时间:window.onload = function(){ if( window.chrome ){ var loadtime = window.chrome.loadTimes(); console.log('开始加载时间: '+loadtime.startLoadTime); console.log('文档加载完成时间: '+loadtime.finishDocumentLoadTime); console.log('页面加载完成时间: '+loadtime.finishLoadTime); // ... } } 欢迎各位提出意见或建议。
2024年10月21日
9 阅读
0 评论
0 点赞
2024-10-21
使用CSS3实现卡牌的旋转切换效果
我们经常会在游戏里看到一些几张卡牌左右切换的效果,中间的一张最突出醒目,向左或向右滑动可切换到另一张,今天我们就用CSS3来实现下这种效果。我们先来看个demo,具体的样式各位可以自己调整: 12345 (PC下可点击按钮切换,移动端可左右滑动切换) 从效果上我们可以看到,这5个div可以左右的切换,每次切换时总会有一个在中间显眼的位置进行展示。在切换时,看起来是div进行了移动,进行了DOM的增删操作。但是如果审查下元素,就能看到,DOM元素没有变换位置,它依然在那个位置,我们只是切换了每个元素上的class,于是页面上的位置看起来是发生了变化。其实原理就是这样的: 不进行DOM的增删,为每个位置上的div都写上特定的样式,每个div都进行绝对定位,然后进行样式的轮播。 每次切换都有个0.6s过渡过程:-webkit-transition: all 0.6s; transition: all 0.6s; 比如从左往右的class分别为:item_0, item_1, item_cur, item_3, item_4,每个class都是当前所在div的定位,向左滑动时,右边的div会切换到中间,这样class从左往右就变成了item_1, item_cur, item_3, item_4, item_0。var egg_change = function(type){ var $demo = $('.demo'), index = parseInt( $demo.attr('index_cur')||2 ), $item = $('.demo .item'), len = $item.length; if( type=='left' ){ index = (index+1)%len; }else{ index = (index-1+len)%len; } $demo.attr('index_cur', index); $item.removeClass('item_0 item_1 item_3 item_4 item_cur'); $item.eq( (index-2+len)%len ).addClass('item_0'); $item.eq( (index-1+len)%len ).addClass('item_1'); $item.eq(index).addClass('item_cur'); $item.eq( (index+1)%len ).addClass('item_3'); $item.eq( (index+2)%len ).addClass('item_4'); }
2024年10月21日
6 阅读
0 评论
0 点赞
1
...
20
21
22
...
125