时间

时间戳(毫秒数)不分时区,即UTC时间所累积的毫秒数,UI必须获得时间戳或者UTC时间的字符串才能正确显示浏览器本地时间。

方案1、后台数据库存放本地时间,返回时间戳给UI。

后台数据库存放本地时间,类型为timestamp或datetime,数据中存放和显示都为本地时间。但它转为时间戳时,还是它对应的UTC时间(本地时间减去时区)所累积的毫秒数。即本地时间对应的时间戳与UTC时间对应的时间戳是相同的,因为时间戳不分时区,都是UTC时间所累积的毫秒数。UI用new Date(时间戳),生成一个时间对象,这个对象的输出都是浏览器本地时间(毫秒数转成UTC时间,再加上时区),此时用format()就可以输出浏览器的本地时间。

方案2、后台数据库存放本地时间,返回服务器本地时间的字符串给UI
方案错误。UI不知道服务器的时区,无法算出时间戳,UI只能显示服务器的本地时间了。当浏览器跟服务器在同一个时区,那么结果正确。
方案3、后台数据库存放UTC时间,返回时间戳给UI
方案错误。数据库中存放UTC时间,转成时间戳时会减去时区,因此返回给UI的是一个错误的时间戳(实际的UTC时间减去服务器时区,所累积的毫秒数)。UI不知道服务器的时区,因此无法计算时间戳。当浏览器跟服务器在同一个时区,那么,UI把后台返回的时间加上时区,能得到正确的时间。
方案4、后台数据库存放UTC时间,返回时间字符串给UI
UI将返回的时间加上时区,得到浏览器本地时间。

new Date("2013-02-08T01:30:26.000Z") ISO 8601 相当于
new Date("2013-02-08 09:30:26 GMT+00:00")
new Date("2013-02-08 09:30:26") 相当于 new Date("2013-02-08 09:30:26 GMT+08:00")

时间处理库:moment.js

图片

JPEG:有损压缩,线条和文字容易产生锯齿
PNG:无损压缩,支持透明度
GIF:无损压缩,支持动画,只支持256种颜色,只支持全透明

WebP:腾讯智图,图片压缩工具  智图客户端下载_图片压缩在线工具_在线制作webp
根据dpr区分下载图片:
1、background: image-set(url(foo.png) 1x,url(foo@2x.png) 2x);
2、媒体查询

exif.js

图片EXIF信息查看器:EXIF信息查看器

问题:iphone拍摄的照片,在电脑上旋转,后在网页中显示时方向出现变化

方案:

1、npm install exif-js --save

2、自动还原图片工具模块

import EXIF from 'exif-js';//旋转图片到正常
const _rotateImg = (imgFile) => {return new Promise((resolve, reject) => {EXIF.getData(imgFile, function () {let exifTags = EXIF.getAllTags(this);let reader = new FileReader();reader.readAsDataURL(imgFile);reader.onload = e => {let imgData = e.target.result;// 8 表示 顺时针转了90// 3 表示 转了 180// 6 表示 逆时针转了90if (exifTags.Orientation == 8 ||exifTags.Orientation == 3 ||exifTags.Orientation == 6) {//翻转//获取原始图片大小const img = new Image();img.src = imgData;img.onload = function () {let cvs = document.createElement('canvas');let ctx = cvs.getContext('2d');//如果旋转90if (exifTags.Orientation == 8 ||exifTags.Orientation == 6) {cvs.width = img.height;cvs.height = img.width;} else {cvs.width = img.width;cvs.height = img.height;}if (exifTags.Orientation == 6) {//原图逆时针转了90, 所以要顺时针旋转90ctx.rotate(Math.PI / 180 * 90);ctx.drawImage(img,0,0,img.width,img.height,0,-img.height,img.width,img.height);}if (exifTags.Orientation == 3) {//原图逆时针转了180, 所以顺时针旋转180ctx.rotate(Math.PI / 180 * 180);ctx.drawImage(img,0,0,img.width,img.height,-img.width,-img.height,img.width,img.height);}if (exifTags.Orientation == 8) {//原图顺时针旋转了90, 所以要你时针旋转90ctx.rotate(Math.PI / 180 * -90);ctx.drawImage(img,0,0,img.width,img.height,-img.width,0,img.width,img.height);}resolve(cvs.toDataURL('image/png'));}}else {resolve(imgData);}}});});
}export default _rotateImg;

PWA

Progressive Web APP 渐进式Web应用:用于实现离线加载能力、离线使用能力、消息推送能力的一套技术方案

APP化:图标添加到主屏,全屏运行

应用缓存:Application cache,由于编程能力差、无法清理缓存、没有路由机制,将被废弃

缓存控制:service worker + cache storage

本地存储:local storage、session storage

本地数据库:Web SQL、IndexedDB

服务器端推送:SSE、web socket

客户端推送:Web Notification

Servcie worker + Cache storage

self

主窗口中,self == window = parent

iframe中,self == window != parent

在web worker 和 service worker中,没有window,全局对象是 self

主线程中注册service worker脚本:navigator.serviceWorker.register('./serviceWorker.js');

service worker线程生命周期:installing -> installed -> activating -> activated

service worker脚本中监听事件

//service worker被安装,这时添加缓存cache.open(cacheName) -> cache.addAll(fileNames)

slef.addEventListener("install", function)

// 当前页面的service work被激活,这时可以删除以往的缓存caches.delete(cacheName)

slef.addEventListener("activate", function)

// 请求文件,这时可以直接返回已经缓存的文件event.responseWith() -> caches.match(event.request)

slef.addEventListener("fetch", function)

Web Notification

Notification.requestPermission()   // 向用户请求允许

Notification.permission               // 用户允许状态

new Notification(title, options)  // 推送消息

Notification.close()                    // 关闭消息

微信公众号

微信公众号网页开发

授权流程
1、设置授权回调域名:微信公众平台-接口权限-网页授权获取用户基本信息
2、自定义菜单:微信公众平台-自定义菜单  或者 微信公众平台接口调试工具-发送请求
方案一:菜单的URL设置为 https://open.weixin.qq.com/connect/oauth2/authorize?appid=&redirect_uri=&response_type=code&scope=snsapi_userinfo#wechat_redirect
URL中包含 appId 和 授权后要跳转到的URL(encodeURIComponent 处理后)
方案二:菜单的URL设置为 简单地址,后端判断是否已授权,未授权则重定向到方案一的地址
3、引导用户访问以上URL,显式授权:出现授权页面,点击授权;静默授权:用户已关注该公众号,不出现授权页面
4、跳转到redirect_uri/?code=10003
5、公众号后端请求 https://api.weixin.qq.com/sns/oauth2/access_token?appid=&secret=&code=&grant_type=authorization_code
URL中包含 appId,开发者密码secret,从4中得到的code
得到 {"access_token":"授权凭证", "openid":"用户标识" }
6、公众号后端请求 https://api.weixin.qq.com/sns/userinfo?access_token=&openid=&lang=zh_CN
URL中包含 5中得到的 access_token 和 openid
得到用户基本信息

JS-SDK调用流程
1、设置JS接口安全域名:微信公众平台-公众号设置-功能设置-JS接口安全域名
2、公众号后端请求 https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=&type=jsapi
URL中包含 access_token,得到jsapi_ticket { "ticket":""}
3、公众号后端生产 随机字符串noncestr, 时间戳timestamp, 当前网页的url(不包含#及其后面部分)
4、拼接成jsapi_ticket=&noncestr=&timestamp=&url=,计算sha1(拼接值),得到签名signature,返给前端
5、前端引入JS-SDK:http://res.wx.qq.com/open/js/jweixin-1.2.0.js
6、前端调用前配置
wx.config({
    debug: true, 
    appId: '',
    timestamp: ,
    nonceStr: '',
    signature: '',
    jsApiList: [需要使用的JS接口列表]
});
7、
wx.ready(function(){
    // SDK接口调用
});

微信支付流程

一、设置支付目录:微信商户平台-商户平台-->产品中心-->开发配置

二、下单
1、前端下单,后端调用微信支付系统下单API,得到prepay_id
2、后端生成 时间戳timestamp,随机字符串nonceStr,支付签名paySign,和prepay_id一起返给前端
三、支付
1、调用支付接口
wx.chooseWXPay({
timestamp: 0, 
nonceStr: '',
package: '', // prepay_id
paySign: '',
success: function (res) {
// 支付成功后的回调函数
}
});
2、用户确认支付,微信支付系统给微信客户端返回支付信息;同时异步通知后端支付结果
四、展示支付结果
1、前端支付接口成功回调,向后端查询支付结果,后端未有结果,则向微信支付系统查询
2、前端展示支付结果

微信网页对比浏览器网页

微信网页支持微信的很多能力,例如扫描二维码、支付

图片前端压缩

基础知识

Data URL
格式:data:image/jpeg;base64,Base64字符串
      data:text/csv;charset=utf-8,内容

来源:FileReader.readAsDataURL()、canvas.toDataURL()、btoa()
      
Blob URL
格式:blob:http://127.0.0.1:8090/f0e5d6f6-a92c-4059-8506-28ca72fcb632

Blob 对象
来源:new Blob([ArrayBuffer])、new Blob([ArrayBuffer视图])、canvas导出
功能:存储二进制数据,被FileReader读取
属性:size,type
方法:
    slice:剪切

File 对象
继承:file.__proto__=File,file.constructor=File,File.__proto__=Blob
来源:文件选择框、new File([blob], name)
属性:name,type,size

FileReader 对象
来源:new FileReader
功能:读取Blob 对象
方法:
    readAsDataURL:读取成base64 Data URL,可被<img src>引用
    readAsBinaryString:读取成BinaryString
    readAsArrayBuffer:读取成ArrayBuffer对象

BinaryString
功能:用单字节字符来表示一个字节,单字节字符组成的字符串来表示二进制数据
来源:FileReader.readAsBinaryString()、atob(DataUrl.split(",")[1])

ArrayBuffer对象(类型化数组)
功能:即内存中的一段固定长度的空间
来源:new ArrayBuffer(length)、FileReader.readAsArrayBuffer()
属性:byteLength

ArrayBufferView(以 Uint8Array 为例)
功能:ArrayBuffer的视图,将ArrayBuffer的表示成一个数组,数组的元素为ArrayBuffer中8比特(一个字节)所对应的一个无符号整数
其他视图:Int8Array(8比特有符号整数数组)、Uint16Array(16比特无符号整数数组)、Uint32Array(32比特无符号整数数组)等
来源:new Uint8Array(arrayBuffer); 
for (let i = 0; i < BinaryString.length; i++) {
    arrayBufferView[i] = BinaryString.charCodeAt(i);
}

FormData 对象
来源:new FormData() 或 new FormData(<form>元素);
功能:构造表单数据,被 XMLHttpRequest.send()发出
方法:
    append:添加字段,可以添加string、blob、file
    delete:删除字段

Image 对象
继承:img.__proto__=HTMLImageElement,即 <img>。另外img.constructor=HTMLImageElement,img.constructor不是其构造器Image,是其构造器的prototype.constructor
来源:new Image()
属性:src,height,width

HTMLCanvasElement 对象
来源:document.createElement('canvas')
功能:绘制图形,导出图形数据
方法:
    toDataURL:导出成Base64字符串,可被<img>的src引用
    toBlob:导出Blob对象
    
URL
方法:
    createObjectURL(blob):构造Blob URL;可以被 <a href> ,用于把前端生成的数据作为文件来下载;用于<img src>显示大图片时,比Data URL性能更好
    URL.revokeObjectURL(url):释放Blob URL对应的文件数据

前端图片压缩过程

1、<input type=file> 选取文件得到 file
2、用fileReader读取file,得到Data URL
3、用Data URL构造成 image
4、用image绘制特定尺寸的Canvas
5、Canvas导出blob 用于上传,或导出 Data URL 用于显示

压缩后上传
1、将blob转成新file,new File([blob], 原file.name),这一步可选
2、用formData包装 新file,最终 XMLHttpRequest.send(formData);

function compressImp(file, resolve, reject)
{if (file.type.indexOf("image") === 0) {let reader = new FileReader(),img = new Image();// 将 file 读取成 Data urlreader.readAsDataURL(file);reader.onload = function (e) {// 用 Data url 构造 imageimg.src = e.target.result;};img.onload = function () {let canvas = document.createElement('canvas');let context = canvas.getContext('2d');// 图片原始尺寸let originWidth = this.width;let originHeight = this.height;// 最大尺寸限制,可通过设置宽高来实现图片压缩程度let maxWidth = 300,maxHeight = 300;// 目标尺寸let targetWidth = originWidth,targetHeight = originHeight;// 图片尺寸超过300x300的限制if (originWidth > maxWidth || originHeight > maxHeight) {if (originWidth / originHeight > maxWidth / maxHeight) {// 更宽,按照宽度限定尺寸targetWidth = maxWidth;targetHeight = Math.round(maxWidth * (originHeight / originWidth));} else {targetHeight = maxHeight;targetWidth = Math.round(maxHeight * (originWidth / originHeight));}}// canvas对图片进行缩放canvas.width = targetWidth;canvas.height = targetHeight;// 清除画布context.clearRect(0, 0, targetWidth, targetHeight);// 用image 绘制 canvascontext.drawImage(img, 0, 0, targetWidth, targetHeight);// 非 IE,返回 File对象if(canvas.toBlob){canvas.toBlob((blob)=>{// blob 转 file,因为blob没有文件名信息let newFile = new File([blob], file.name);resolve(newFile);}, 'image/jpeg', 0.92);}else{  // 兼容IE,返回Base64,IE下无法构造File对象let dataUrl = canvas.toDataURL('image/jpeg', 0.92);resolve(dataUrl);}};}
}
export default function compress(file){return new Promise(function(resolve, reject) {compressImp(file, resolve, reject)});
}

动画 与 过渡

CSS3 transition 过渡

缓动效果:线性、慢进、慢出、贝塞尔曲线cubic-bezier
Vue中, 使用<transition>可以在 元素插入和移除时,添加过渡效果

CSS3 animation 关键帧动画

效果:可以设置多个关键帧
Vue中, 使用<transition>可以在 元素插入和移除时,添加关键帧动画

使用动画:animation: myfirst 5s;    参数为动画名和动画时间

定义动画:

                         @keyframes myfirst{from   {background: red;}50%  {background: blue;}to  {background: green;}}

动画循环:animation-iteration-count(循环次数),animation-direction(是否往返循环)

动画事件:

element.addEventListener("animationstart", listener, false);         // 监听动画开始事件,listener为事件处理函数
element.addEventListener("animationend", listener, false);          //动画结束
element.addEventListener("animationiteration", listener, false);  //动画新一周期开始

Velocity.js  脚本动画

效果:链式动画(给一个元素连续添加多个动画)、循环、回放、各种缓动曲线
Vue中,<transition>的钩子(元素插入前事件、元素插入后事件、元素移除前事件、元素移除后事件)可以调用Velocity.js,实现脚本动画
Velocity 缓动
1、预设的缓动曲线:参考 https://easings.net/  ,包括 反弹、起跳等效果
2、CSS3 transition 支持的缓动曲线,即慢近慢出、贝塞尔曲线
3、物理学弹性效果:缓动模式设置成'spring',或者具体的[tension(张力),friction(摩擦力)]
4、跳跃效果:缓动模式设置成 [steps(步数)]

注意:

针对同一个元素的同一个样式,跟transition不能叠用

有些transitio支持的过渡,Velocity不支持,比如背景颜色

Animate.css 预设的动画样式

场景:原地晃动、渐入渐出

缓动效果:弹跳、显隐、滑动、滚动、扭动、旋转、翻转、缩放、摆动
Vue中,给<transition>加上Animate.css的类,即可应用动画

注意:

同一个位置,元素A滚出,同时元素B滚入;元素A滚出前,要置为绝对定位,否则会占住位置。

对比选型:

简单过渡用transition

只考虑原地晃动 和 渐入渐出,使用Animate.css

在一定范围内运动,使用Velocity.js

GSAP 动画库

    let animate1 = gsap.to(mesh.position, {x: 300,duration: 5,ease: "bounce.inOut", // 速度曲线delay: 2,repeat: 2,yoyo: true,   // 往返onStart: ()=>{console.log('动画开始');},onComplete: () => {console.log('动画结束');}});

新兴方案

React Native:Facebook推出的Native App方案,使用React框架开发

Weex:阿里推出的Native App方案,使用Vue框架开发

Flutter:Google推出的Native App方案,使用Dart语言开发

Hummer:滴滴推出的轻量级跨端技术框架,支持Vue 和 React 开发

WebAssembly:将编译型语言编译成WebAssembly,从而能在浏览器运行

Serverless:云平台提供的FaaS(Functions as a Service) 和 BaaS(Backend as a Service),减少后端程序和运维

FaaS:函数服务化,即运行函数的平台,例如函数计算服务,FaaS可以调用BaaS

BaaS:后端服务化,例如CDN服务、对象存储服务、日志服务、云监控、云数据库、消息队列

小程序云开发:小程序代码中直接调用FaaS和BaaS,例如操作数据库。开发简单应用甚至可以不用后端程序

中台:通用能力的平台化

技术中台:后端技术、运维技术的平台化,例如微服务开发框架、Devops平台、PaaS平台、容器云等
业务中台:业务的平台化(微服务化),例如用户中心、订单中心等
组织中台:企业内部组织的平台化,例如资源调度中心、内部创新孵化组织

屏幕适配

参考
https://github.com/amfe/article/issues/17
https://github.com/amfe/lib-flexible
http://www.cocoachina.com/webapp/20150715/12585.html

方法

弹性布局:flex、grid、居中、calc()
样式选择:媒体查询、媒体信息作为选择器前缀(例如<html [dpr=2]>)
相对尺寸:%,rem(设置<html font-size=dip数/10>)、vw、rpx
自适应总体方案:高度用px、字体大小用px、宽度用vw或rem、rpx、calc()

像素

px(pixels):物理像素,硬件像素,设备像素,显示像素
dp,dip(deveice independent pixels):逻辑像素、设备无关像素、CSS像素
pt(point):1/72英寸
dpr(devicePixelRatio): 设备像素比,即 1dip包含了多少个px,即px数 / dip数
ppi,dpi:像素密度(像素每英寸),斜向一英寸里的物理像素数量
em: 相对于父元素的font-size的相对单位。
rem: 相对于根元素的font-size的相对单位。
vw: 1% 布局视口宽度
vh: 1% 布局视口高度
resolution:分辨率,横向物理像素数 * 纵向物理像素数

屏幕

设备尺寸列表 https://material.io/devices/

ppi与默认dpr对应关系

^ 显示分辨率 ppi 默认dpr
ldpi 240*320 120 0.75
mdpi 320*480 160 1.0
hdpi 480*800 240 1.5
xhdpi 720*1280 320 2.0
Retina屏(视网膜屏): ppi 大于320

案例 – iPhone5
resolution:640 * 1136,屏幕尺寸:4英寸
ppi = 开根号(1136 * 1136 + 604 * 640) / 4 = 326。默认dpr:2
逻辑像素:640 * 1136 / 2 = 320 * 568

总结
屏幕宽度dip数,即宽度px数 / dpr,都在360左右

JS读取屏幕信息

screen.width 屏幕的dip数
window.innerWidth 浏览器的dip数(包含滚动条占据的宽度)
document.documentElement.clientWidth viewport的dip数
document.documentElement.offsetWidth 根元素的dip数
window.devicePixelRatio 屏幕dpr
orientationchange 屏幕转向事件

视口

屏幕尺寸 = px尺寸 * px数 = dip尺寸 * dip数 = px尺寸 * dpr * dip数
视口dip数:布局宽度,即document.documentElement.clientWidth,与窗口的宽度window.innerWidth可以不同

viewport 设置

<meta name="viewport" content="width=deveice-width,initial-scale=1, mininum-scale=,maximum-scale=,user-scalable=no">

width:视口的dip数,相当一部分手机浏览器默认为 980px
deveice-width:屏幕的默认dip数,即px数 / 默认dpr
initial-scale:初始缩放比例,默认值为auto,即缩放到屏幕尺寸
user-scalable:是否允许手动缩放
mininum-scale:最小手动缩放比例
maximum-scale:最大手动缩放比例

缩放实践

一、桌面浏览器,设置viewport缩放,无效

二、桌面浏览器,手动缩小,就是改变dpr:
1、dpr变小,视口dip数变大
2、相对(于视口)宽度的元素,尺寸不变,dip数变大。
3、固定宽度的元素,dip数不变,尺寸变小。
4、文字无法无限缩小,缩小到一定程度后继续缩小,尺寸不变,dip数变大。
桌面浏览器的window.devicePixelRatio 与 实际dpr 相等

三、桌面浏览器,手动放大,与手动缩小效果相反

四、移动浏览器手动缩放
视口、百分比宽度元素、固定宽度元素,全都是尺寸缩放,dip数不变。视口尺寸不能缩小到比屏幕小。

四、移动浏览器,设置initial-scale放大(initial-scale大于1)
1、有些浏览器无效
2、效果与手动放大相同

五、移动浏览器,设置initial-scale缩小(initial-scale为auto或小于1)
1、实际dpr变小,视口dip数不变
2、相对(于视口)宽度的元素,dip数不变,尺寸变小。
3、固定宽度的元素,dip数不变,尺寸变小。
4、文字缩小到不能再缩小的程度
5、当视口缩小到device-width后,改为视口dip数变大(有极限),尺寸不变
自动缩小后,实际dpr与默认dpr不再相等,window.devicePixelRatio 仍然等于 默认dpr

viewport 设置案例

一、未设置
默认为 width=980px,initial-scale=auto

二、viewport只设置width,不设置initial-scale
默认为 initial-scale=auto
使用场景:设计稿宽为750px(iPhone6),可以设置width=750px,自动缩放后,所有元素等比例缩小

三、viewport只设置initial-scale=1,不设置width
默认为 width=device-width

四、viewport只设置initial-scale !=1,不设置width
那么 Android width=980px,IOS width=device-width

五、viewport设置 width=device-width, initial-scale=1
那么布局宽度约为360px,这时候实际dpr 正好等于 默认dpr

屏幕适配方案

viewport方案一

<meta name="viewport" content="width=750px, user-scalable=no">

width=设计稿的宽度,initial-scale=auto
缺点:自动缩放,不够精细

viewport方案二

<meta name="viewport" content="width=deveice-width, initial-scale=1, user-scalable=no">

缺点:不能解决border:1px 问题

viewport方案三
初始viewport: <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
重设viewport:

let defaultDpr = window.devicePixelRatio || 1;   // 默认dpr
let portWidth = document.documentElement.clientWidth * defaultDpr;   // 物理像素数
let viewport = document.querySelector('meta[name="viewport"]');
viewport.setAttribute('content', 'width=' + portWidth  + ', initial-scale=' + 1 / defaultDpr + ',user-scalable=no');
// 或者 viewport.setAttribute('content', 'width=device-width, initial-scale='+ 1 / defaultDpr  + ',user-scalable=no');
// 由 上文 “缩放实践-五” 可以得出以上两行效果是一样的,效果都是 视口dip数 等于 px数

相对宽度方案

  let remSize = (document.documentElement.clientWidth / 10).toFixed(2);document.documentElement.style.fontSize = remSize + "px";window.remSize = remSize;window.rem2px = function(remNum) {return parseFloat(remNum) * remSize;};window.px2rem: function(pxNum) {return parseFloat(pxNum) / remSize;};

使用vw 或 rem,rem比vw兼容性好

n倍图方案

 let defaultDpr = window.devicePixelRatio || 1;document.documentElement.setAttribute('data-dpr',  window.devicePixelRatio );window.defaultDpr  = defaultDpr;

n倍图应用于默认dpr为n的屏幕,根据不同[data-dpr] 引用不同@的图片
2倍

设计稿px 转 css单位 方案
以750px设计稿为例,对应的默认dpr为2

   // px 转 rem,适用于相对宽度的元素.px2rem(@name, @px){@{name}: @px / 75 * 1rem;}// px 转 px,适用于固定宽度的元素,例如字体、1px边框
// 前提为采用了 viewport方案三
.px2px(@name, @px){@{name}: round(@px / 2) * 1px;[data-dpr="2"] & {@{name}: @px * 1px;}[data-dpr="2.5"] & {@{name}: round(@px * 2.5 / 2) * 1px;}[data-dpr="2.75"] & {@{name}: round(@px * 2.75 / 2) * 1px;}[data-dpr="3"] & {@{name}: round(@px / 2 * 3) * 1px}[data-dpr="4"] & {@{name}: @px * 2px;}
}

前端方案(时间/图片/PWA/微信公众号/图片前端压缩/动画与过渡/新兴方案/屏幕适配)相关推荐

  1. 微信公众号的前端热门文章及链接(不定期更新)

    2020/4/11 001.万字解析微前端.微前端框架qiankun以及源码 作者:晒兜斯 https://segmentfault.com/a/1190000022275991 本文将针对微前端框架 ...

  2. 第三方网站不能调用微信公众平台里的图片了 显示此图片来自微信公众号平台未经允许不可引用...

    下午ytkah在自己小博客搜索时看到有几篇文章图片显示不了,再访问一些网站时发现有些图片无法显示出来,显示"此图片来自微信公众号平台未经允许不可引用",如下图所示,这个应该是最近微 ...

  3. 微信公众号图片素材一键删除小工具

    微信公众号图片素材上限100000,看似很多,但随着每天发文累计的图片素材会越来越多,一不小心就到达上限,便无法继续发文,这个时候就要承受老板的狂风怒火. 微信公众号后台带有素材图片批量删除功能,操作 ...

  4. 微信公众号开发前端逻辑

    近来做微信公众号开发,记录一下前端的开发过程. 其实微信公众号就是提供一个入口,来把自己开发的项目可以链接到微信公众号,来达到用微信访问的目的.自己的项目就是一个移动端的网页.可以用任何技术实现,和微 ...

  5. 【Python爬虫】下载微信公众号图片

    大家用爬虫下载图片时肯定遇到过https://demo?wx_fmt=jpeg链接的图片,常见的就是微信公众号的图片. 遇到链接图片用普通的方式是无法爬取下来的,我们可以用urllib.request ...

  6. 添加管理微信公众号图片素材-微信公众号使用教程8

    微信公众号发送消息给粉丝时, 有一种素材是经常用到的, 那就是图片. 公众号使用图片的方式 在公众号中使用图片有两种方式: 一种是直接复制粘贴, 另外一种是先把图片上传到微信公众号的素材库中, 在使用 ...

  7. 爬虫微信公众号图片无法显示

    爬虫微信公众号图片无法显示 html头部增加 <meta name="referrer" content="never">

  8. 微信公众号 餐饮 前端源码_成都餐饮茶楼微信公众号开发方案

    在很多人的印象中,传统的餐饮茶楼就应该做好自己的生意,和互联网是拉不上关系的,甚至格格不入.但是就用独立思考的餐饮茶楼客户提出了新的思路,能不能用微信公众号来吸引用户,让微信公众号成为用户的入口,而不 ...

  9. 微信公众号支付前端部分流程

    上周公司安排了微信公众号支付开发任务,经过快一周的不断填坑,终于把支付搞定,现在把遇到的问题和开发步骤记录一下,方便遇到同样问题的老铁们节省一些时间,少入些坑,先说一下本文不包含的内容,因为这些并不难 ...

最新文章

  1. 显示DataGrid序号的一个适用的方法
  2. 【转载】从多项式曲线拟合到模式识别的相关概念
  3. nacos使用_使用Nacos的CMDB实现微服务的就近访问!
  4. java开发环境:还在配classpath?你out啦!
  5. spring 国际化-i18n
  6. 企业利用Pinterest平台推广9条建议
  7. python copy与deepcopy (拷贝与深拷贝)
  8. IOS-简单WebView的使用
  9. Java教程:Java字符串替换实例
  10. Ansible详解(十)——Ansible Template模板基础
  11. 基于python、jupyter-notebook 的金融领域用户交易行为分析
  12. mysql5.7.19zip,mysql5.7.19zip详细安装过程和配置
  13. 【学习笔记】powell法的python实现
  14. LearnGL - 13 - PointLight - 点光源
  15. WORD2003无法打开WORD2000文档解决方法
  16. Apache Flink 漫谈系列(12) - Time Interval(Time-windowed) JOIN
  17. 【编程题】【Scratch一级】2019.12 小狗长大记
  18. 个人修改机智云apk之出现couldn‘t find “libSDKLog.so“错误导致机智云apk在真机上调试出现keeps stopping错误解决方法
  19. stm32h7内存分配_【STM32H7教程】第26章 STM32H7的TCM,SRAM等五块内存的超方便使用方式...
  20. 虚拟 DOM 是什么 有什么优缺点

热门文章

  1. 奶块服务器正在维护是什么意思,奶块例行维护什么意思 | 手游网游页游攻略大全...
  2. 10万字智慧政务大数据治理平台解决方案(word)
  3. MTK Android 13平台开关机动画铃声客制化
  4. 最小二乘法拟合直线簇交点及Ransac拟合
  5. Python3-爬虫~selenium\phantomjs\豆瓣应用例子
  6. Windows服务 FLEXnet Licensing service 64
  7. setp函数--Matplotlib
  8. c#(.net) 导出 word表格
  9. java 捕获异常还是抛出异常
  10. Vmware与主机间共享文件的七种方法