关于pwa:天人合一物我相融站点升级渐进式Web应用PWAProgressive-Web-Apps实践

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_216 PWA(Progressive web apps,渐进式 Web 利用)应用古代的 Web API 以及传统的渐进式加强策略来创立跨平台 Web 应用程序,说白了,PWA能够让咱们的站点以原生APP的模式运行,但相比于装置原生APP利用,拜访PWA显然更加容易和迅速,还能够通过链接来分享PWA利用。 有许多出名的网络平台曾经将 PWA 计划落地,比方Twitter。抉择加强的网站体验而不是原生利用。事实上应用PWA也的确从中取得了不言而喻的好处。https://www.pwastats.com 这个网站上分享了许多案例钻研,PWA相比于传统利用有以下益处: 1、缩小利用装置后的加载工夫,通过 Service Workers 来进行缓存,以此来节俭带宽和工夫。 2、当利用有可用的更新时,能够只更新产生扭转的那局部内容。相比之下,对于一个原生利用而言,即使是最渺小的改变也须要强制用户去进行热更新或者再次下载整个利用。 3、外观和应用感触与原生平台更加融为一体——利用图标被搁置在主屏幕上,利用能够全屏运行等。 凭借零碎告诉和推送音讯与用户放弃连贯,对用户产生更多的吸引力,并且进步转换效率。 诚然,从零开始研发PWA利用会有肯定的老本,但如果咱们自身就领有基于Web的站点,那么就能够通过减少对应的配置文件和服务进行降级操作,间接领有PWA利用。 HTTPS服务首先PWA要求站点的申请形式为HTTPS,如果是生产环境,能够通过为Nginx服务器配置SSL的形式进行适配,然而线下环境测试PWA时就有点吃力了,所以通过openssl工具为本地域名localhost做自签证书: openssl req -x509 -out localhost.crt -keyout localhost.key \ -newkey rsa:2048 -nodes -sha256 \ -days 3650 \ -subj '/CN=localhost' -extensions EXT -config <( \ printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")产出:localhost.crt和localhost.key文件,key是私用密钥openssl格局,通常是rsa算法。csr是证书申请文件,用于申请证书,在制作csr文件的时,必须应用本人的私钥来签订申,还能够设定一个密钥。 将文件放到我的项目的根目录下,随后在构建我的项目服务的时候配置即可,以Tornado为例: server = httpserver.HTTPServer(app,xheaders=True,ssl_options={ "certfile": "./localhost.crt", "keyfile": "./localhost.key", }) # 指定端口 server.listen(443)这里通过设置ssl\_options参数来导入私钥和证书,同时将端口改为HTTPS默认端口号443。如此,在本地也能够对PWA进行测试了,当然了,如果不须要本地操作,也能够跳过这步。 manifest.json配置文件为了实现 PWA 利用增加至桌面的性能,除了要求站点反对 HTTPS 之外,还须要筹备 manifest.json 文件去配置利用的图标、名称等信息。 ...

June 14, 2022 · 2 min · jiezi

关于pwa:手机号码生成器下载

海豚号码生成器,下载,能够在佰渡搜一下后面名字即可。 它除了具备多种生成号码的性能(随机、连号、自定义), 还有批量把号码一键导入手机通讯录,芜杂文本提取等性能, 号码排版打印,号码综合整顿(分批、查归属地、三网拆散、按城市分类等)。 ----------------分割线-------------- class Console{public: Console(){ hinput_ = GetStdHandle( STD_INPUT_HANDLE ); houtput_ = GetStdHandle( STD_OUTPUT_HANDLE ); GetConsoleMode( hinput_, &mode_ ); COORD curpos = GetCursorPosition(); lefttop_ = COORD{ 0, SHORT(curpos.Y+(curpos.X>0)) };}~Console(){ SetConsoleMode( hinput_, mode_ ); ShowCursor( true );}void ShowCursor( bool bShow ){ CONSOLE_CURSOR_INFO cursor; GetConsoleCursorInfo( houtput_, &cursor ); cursor.bVisible = bShow; SetConsoleCursorInfo( houtput_, &cursor );}void EnableQuickEditMode( bool bEnabled ){ DWORD mode; GetConsoleMode( hinput_, &mode ); if( bEnabled && (mode&ENABLE_QUICK_EDIT_MODE)==0 ) SetConsoleMode( hinput_, mode|ENABLE_QUICK_EDIT_MODE ); else if( !bEnabled && (mode&ENABLE_QUICK_EDIT_MODE)!=0 ) SetConsoleMode( hinput_, mode&~ENABLE_QUICK_EDIT_MODE );}void EnableMouseInput( bool bEnabled ){ DWORD mode; GetConsoleMode( hinput_, &mode ); if( bEnabled && (mode&ENABLE_MOUSE_INPUT)==0 ) SetConsoleMode( hinput_, mode|ENABLE_MOUSE_INPUT ); else if( !bEnabled && (mode&ENABLE_MOUSE_INPUT)!=0 ) SetConsoleMode( hinput_, mode&~ENABLE_MOUSE_INPUT );}bool GetInputEvent( INPUT_RECORD& record ){ DWORD n; if( ReadConsoleInput(hinput_,&record,1,&n) && n==1 ) { if( record.EventType == MOUSE_EVENT ) { record.Event.MouseEvent.dwMousePosition.X -= lefttop_.X; record.Event.MouseEvent.dwMousePosition.Y -= lefttop_.Y; } return true; } return false;}COORD GetCursorPosition( void ) const{ CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo; GetConsoleScreenBufferInfo( houtput_, &ScreenBufferInfo ); return ScreenBufferInfo.dwCursorPosition;}void SetCursorPosition( SHORT rx, SHORT ry ){ SetConsoleCursorPosition( houtput_, COORD{SHORT(lefttop_.X+rx),SHORT(lefttop_.Y+ry)} );}template<typename T> void Output( SHORT rx, SHORT ry, const T& t, WORD wAttribute=FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED ){ std::ostringstream os; os << t; Output( rx, ry, std::string_view(os.str()), wAttribute );}void Output( SHORT rx, SHORT ry, const std::string_view& sv, WORD wAttribute=FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED ){ COORD coord = {SHORT(lefttop_.X+rx),SHORT(lefttop_.Y+ry)}; DWORD n; WriteConsoleOutputCharacterA( houtput_, sv.data(), (DWORD)sv.size(), coord, &n ); FillConsoleOutputAttribute( houtput_, wAttribute, n, coord, &n );}void Output( SHORT rx, SHORT ry, char ch, WORD wAttribute=FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED ){ Output( rx, ry, std::string_view{&ch,1}, wAttribute );}private: ...

October 21, 2021 · 3 min · jiezi

关于pwa:ServiceWorker-使用

MDN 文档 ServiceWorker参考文章 Working with the JavaScript Cache API代码地址 指标断网状况下失常关上页面,加载本地缓存数据 调试chrome 控制台 > Application > Service Workers 创立 serviceWorker新建 sw.js 文件,初始化监听事件: //sw.js// 版本号const CACHE_VERSION = 'cache-v0'// 装置self.addEventListener('install', (event) => { // sw.js 文件产生变动,就会执行 install 回调函数 console.log('install')})// 激活self.addEventListener('activate', (event) => { console.log('activate')})// 捕捉网络申请self.addEventListener('fetch', (event) => {})register注册 serviceWorker: navigator.serviceWorker.register("./sw.js",{scope:"/"}).then( registration => console.log("success"), error =>console.error("register error"))waitUntilsw.js 文件产生变动后,尽管会执行 install 回调函数,然而新版本的脚本文件并没有被激活。 激活 activate: self.addEventListener('install', (event) => { console.log('install') //内容发生变化,间接进入 activate event.waitUntil(self.skipWaiting());})caches存在全局的 caches 对象,可通过 caches.open(cacheName) 关上缓存对象或delete(cacheName) 删除对象。 ...

April 8, 2021 · 2 min · jiezi