JSSDK使用步骤
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: '', // 必填,公众号的唯一标识timestamp: , // 必填,生成签名的时间戳nonceStr: '', // 必填,生成签名的随机串signature: '',// 必填,签名jsApiList: [] // 必填,需要使用的JS接口列表
});
签名算法见文末的附录1,所有JS接口列表见文末的附录2
步骤四:通过ready接口处理成功验证
wx.ready(function(){// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
步骤五:通过error接口处理失败验证
wx.error(function(res){// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
接口调用说明
所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:
1.success:接口调用成功时执行的回调函数。
2.fail:接口调用失败时执行的回调函数。
3.complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
4.cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
5.trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。
以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:
调用成功时:"xxx:ok" ,其中xxx为调用的接口名
用户取消时:"xxx:cancel",其中xxx为调用的接口名
调用失败时:其值为具体错误信息
音频接口
开始录音接口
wx.startRecord();
停止录音接口
wx.stopRecord({
success: function (res) {
var localId = res.localId;
}
});
监听录音自动停止接口
wx.onVoiceRecordEnd({
// 录音时间超过一分钟没有停止的时候会执行 complete 回调
complete: function (res) {
var localId = res.localId;
}
});
播放语音接口
wx.playVoice({
localId: '' // 需要播放的音频的本地ID,由stopRecord接口获得
});
暂停播放接口
wx.pauseVoice({
localId: '' // 需要暂停的音频的本地ID,由stopRecord接口获得
});
停止播放接口
wx.stopVoice({
localId: '' // 需要停止的音频的本地ID,由stopRecord接口获得
});
监听语音播放完毕接口
wx.onVoicePlayEnd({
success: function (res) {
var localId = res.localId; // 返回音频的本地ID
}
});
上传语音接口
wx.uploadVoice({
localId: '', // 需要上传的音频的本地ID,由stopRecord接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) {
var serverId = res.serverId; // 返回音频的服务器端ID
}
});
备注:上传语音有效期3天,可用微信多媒体接口下载语音到自己的服务器,此处获得的 serverId 即 media_id,参考文档 .目前多媒体文件下载接口的频率限制为10000次/天,如需要调高频率,请登录微信公众平台,在开发 - 接口权限的列表中,申请提高临时上限。
下面开始码代码:
voice.js
var URIstring=location.href.split('#')[0];//获取当前页面的全路径
var url="/zf/ConfigParam?Rurl="+encodeURIComponent(URIstring);//将路径传入后台加密时使用
$(document).ready(function(){
$.ajax({
url :encodeURI(url),// encodeURI(encodeURI(url)),
type : 'POST',
async: false,
dataType : 'json',
timeout : 5000,
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("不好意思,出了点小问题");
},
success : function(req) {
wx.config({
debug: false,//开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: req.appid, // 必填,公众号的唯一标识
timestamp:req.timestamp, // 必填,生成签名的时间戳
nonceStr: req.nonceStr, // 必填,生成签名的随机串
signature:req.signature,// 必填,签名,见附录1
jsApiList:['chooseImage','previewImage','uploadImage','downloadImage',]// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
}
});
var voice = { localId: '', serverId: '' };//全局变量
var END;
var START;
//按下开始录音
$('#talk_btn').on('touchstart', function(event){
event.preventDefault();
START = new Date().getTime();
recordTimer = setTimeout(function(){
wx.startRecord({
success: function(){
// mui('#talk_btn').button('loading');
localStorage.rainAllowRecord = 'true';
},
cancel: function () {
alert('用户拒绝授权录音');
}
});
},300);
});
//松手结束录音
$('#talk_btn').on('touchend', function(event){
event.preventDefault();
// mui('#talk_btn').button('reset');
END = new Date().getTime();
if((END - START) < 1000){
END = 0;
START = 0;
//小于1000ms,不录音
clearTimeout(recordTimer);
mui.toast('录音时长小于1秒不录音',{ duration:'short', type:'div' }) ;
var t=setTimeout(function(){wx.stopRecord()},800);//这里设置800毫秒,是因为如果用户录音之后马上松开按钮,会成 wx.stopRecord不起作用的情况,然后会一直录音,所以时间设置长一点
//clearTimeout(t);
}else{
wx.stopRecord({
success: function (res) {
voice.localId = res.localId;
//$("#vo").val(res.localId);
uploadVoice();
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
}
});
//上传录音
function uploadVoice(){
//调用微信的上传录音接口把本地录音先上传到微信的服务器
//不过,微信只保留3天,而我们需要长期保存,我们需要把资源从微信服务器下载到自己的服务器
wx.uploadVoice({
localId: voice.localId, // 需要上传的音频的本地ID,由stopRecord接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) {
voice.serverId = res.serverId;
/* var uu = /restsh/uploadVoice/" + res.serverId;
$.ajax({//上传到服务器
url : uu,
async : true,
cache : false,
dataType : 'json',
type : 'GET',
data : {},
success : function(req) {
voice.serverId = res.serverId;
$.web.RemoveLoading();
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
$.web.RemoveLoading();
mui.alert("不好意思,出了点小问题","提示","确定");
}
});*/
}
});
}
// 4.4 监听录音自动停止
wx.onVoiceRecordEnd({
complete: function (res) {
voice.localId = res.localId;
//uploadVoice();//上传录音到服务器
alert('录音时间已超过一分钟');
}
});
document.querySelector('#playVoice').onclick = function () {
if (voice.localId == '') {
alert('请先录制一段声音');
//alert('请先使用 startRecord 接口录制一段声音');
return;
}
wx.playVoice({
localId: voice.localId
});
};
// 暂停播放音频
document.querySelector('#stop_btn').onclick = function () {
mui('#playVoice').button('reset');
wx.pauseVoice({
localId: voice.localId
});
};
|
/*使用微信jssdk接口录音,在同一个域只需要授权一次,即第一次使用录音的时候,微信自己会弹出对话框询问是否允许录音,用户点击允许后,之后再使用录音时,便不会再咨询用户是否允许。
在第一次按住录音后,由于用户未曾允许录音,微信会提示用户授权允许在本页面使用微信录音功能,这时用户会放开录音按钮转而去点击允许,在用户允许后,才真正会开始录音,而此时用户早已放开录音按钮,那么录音按钮上便不会再有touchend事件,录音便会一直进行。
解决策略:使用localStorage记录用户是否曾授权,并以此来判断是否需要在刚进入页面是自动录一段录音来触发用户授权*/
if(!localStorage.rainAllowRecord || localStorage.rainAllowRecord !== 'true'){
wx.startRecord({
success: function(){
localStorage.rainAllowRecord = 'true';
setTimeout(function(){
wx.stopRecord({
fail:function(res){
//alert("停止失败");
},
success: function (res) {
var localId = res.localId;
}
});
},800);//这里设置800毫秒,是因为如果用户录音之后马上松开按钮,会成 wx.stopRecord不起作用的情况,然后会一直录音,所以时间设置长一点
//clearTimeout(t);
},
cancel: function () {
alert('用户拒绝授权录音');
}
});
}
wx.error(function (res) {
wx.stopRecord();
alert(res.errMsg);
});
以上是前端js,具体业务具体操作
后台代码
ConfigParam.java
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
public class ConfigParam extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String Rurl=java.net.URLDecoder.decode(request.getParameter("Rurl"),"utf-8");
//System.out.println(Rurl);
Map<String, String> ret= WeixinUtil.getJSSDKData(Rurl,WechatUtil.appId,WechatUtil.appSecret);
JSONObject json=JSONObject.fromObject(ret);
//System.out.println(json.toString());
out.print(json);
}
}
|
WeixinUtil.java 和AccessToken.java
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 公众平台通用接口工具类
*
*
*
*/
public class WeixinUtil {
private static Log log = LogFactory.getLog(WeixinUtil.class);
// 获取access_token的接口地址(GET) 限200(次/天)
public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token? grant_type=client_credential&appid=APPID&secret=APPSECRET";
private static Map<String,AccessToken> tokenMap = new HashMap<String,AccessToken>();
/**
* 获取access_token
*
* @param appid 凭证
* @param appsecret 密钥
* @param flag 是否重新获取
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret,boolean flag) {
AccessToken accessToken = null;
log.info("=================getAccessToken-start");
if(!flag){
accessToken = tokenMap.get(appid);
}
long now = System.currentTimeMillis();
if(accessToken != null && !flag){
long lastTime = accessToken.getCreateTime();
//当accessToken还在有效期内
if(now <= (lastTime + accessToken.getExpiresIn() * 1000) ){
log.info("读取缓存accessToken=="+accessToken);
return accessToken;
}
}
String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setCreateTime(now);
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in") - 300);
log.info("重新获取accessToken=="+accessToken);
} catch (JSONException e) {
accessToken = null;
// 获取token失败
log.error("获取token失败 errcode:"+jsonObject.getInt("errcode")+" errmsg:{"+ jsonObject.getString("errmsg")+"}" );
}
}
log.info("=================getAccessToken-end");
tokenMap.put(appid, accessToken);
return accessToken;
}
/**
* 获取access_token
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret ) {
log.info("getAccessToken:重新获取AccessToken");
return getAccessToken(appid, appsecret, true);
}
public static String JS_API_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
/**
*
* @param accessToken
* @return
*/
public static String getJsapi_ticket(String accessToken){
log.info("=====================getJsapi_ticket:start");
String url = JS_API_URL.replace("ACCESS_TOKEN", accessToken);
JSONObject json = httpRequest(url, "GET", null);
log.info("getJsapi_ticket:"+json);
String jsapi_ticket = "";
try {
jsapi_ticket = json.getString("ticket");
} catch (Exception e) {
log.error("=====================getJsapi_ticket:error"+json);
e.printStackTrace();
}
log.info("=====================getJsapi_ticket:end");
return jsapi_ticket;
}
//JS SDK 中需要的相关的数据
private static Map<String,String > JsSDKMap = new HashMap<String, String>();
public static String getJsapi_ticket_cache(String accessToken ){
String jsapi = JsSDKMap.get(accessToken);
if(jsapi != null){
log.info("读取jsapi_ticket缓存"+jsapi );
return jsapi;
}else{
jsapi = getJsapi_ticket(accessToken);
log.info("刷新Jsapi_ticket:"+jsapi+"===="+accessToken );
JsSDKMap.put(accessToken, jsapi);
}
return jsapi;
}
//获得jsapi_ticket,noncestr,timestamp
public static Map<String ,String> getJSSDKData(String requestUrl,String appid,String appsecret){
log.info("=================getJSSDKData-start");
//1)获取access_token
AccessToken accessToken = getAccessToken(appid, appsecret,false);
String token = accessToken.getToken();
log.info("accessToken:"+accessToken);
//2)获取jsapi_ticket(有效期7200秒
String jsapi_ticket = getJsapi_ticket_cache(token);
log.info("jsapi_ticket:"+jsapi_ticket);
//3)获取//随机字符串
String noncestr = Double.toString(Math.random()).substring(2, 15);//随机字符串
//4)获取 随机时间戳
String timeStamp =((int)(new Date().getTime()/1000))+"";//随机时间戳
//5)获取签名
String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp="+ timeStamp +"&url=" + requestUrl;
log.info("str:" + str);
String signature = SHA1Util.Sha1(str);
Map<String ,String> map = new HashMap<String, String>();
map.put("ticket", jsapi_ticket);
map.put("noncestr", noncestr);
map.put("timestamp", timeStamp);
map.put("signature", signature);
map.put("url", requestUrl);
map.put("appid", appid);
log.info("=================getJSSDKData-end");
return map;
}
/**
* 发起https请求并获取结果
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
log.error("Weixin server connection timed out.");
} catch (Exception e) {
log.error("https request error:{}", e);
}
return jsonObject;
}
}
/**
* 微信通用接口凭证
*
*
*
*/
public class AccessToken {
// 获取到的凭证
private String token;
// 凭证有效时间,单位:秒
private int expiresIn;
private long createTime;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
}
|
uploadVoice
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
//String mediaId=request.getParameter("mediaId");
Map<String, String> map = new HashMap<String, String>();
String mediaId = request.getParameter("mediaId");
String folderName="/app/ss/"+new SimpleDateFormat("yyyy/MMdd/").format(new Date());
try {
File dir = new File(folderName);
if (!dir.exists())
dir.mkdirs();
} catch (Exception ex) {
}
String Str="";
String randstr = UUID.randomUUID().toString().replaceAll("-", "");
String path=folderName+randstr;//绝对路径
String frontName = "" + randstr;//相对路径
String absFileName=path+".jpg";//"D:\\img\\a.jpg";//
String str= DloadImgUtil.downloadMedia(mediaId, absFileName,path+"_240.mp3","2");//调用下载接口
map.put("status", "1");
map.put("msg",Str);
map.put("path", "");
map.put("photoUrl","");
JSONObject json = JSONObject.fromObject(map);
out.print(json);
}
|
记住,大坑来了,由于从微信服务器下载下来的音频格式是amr格式的,为了实现使用h5标签能够播放,需要转成mp3格式
我是使用ffmpeg进行转换的
使用ffmpeg将amr格式转为mp3格式时需注意:windows系统使用ffmpeg.exe,linux系统使用ffmpeg(去官网下载对应版本http://ffmpeg.org/download.html)
DloadVoicUtil.java
public class DloadImgUtil {
private final static String FFMPEG_PATH;
static {
FFMPEG_PATH =DloadImgUtil.class.getResource("ffmpeg.exe").getFile(); //windows系统使用, FFmpeg文件和DloadImgUtil 同一目录下
}
// static {
// FFMPEG_PATH =DloadImgUtil.class.getResource("ffmpeg").getFile(); //linux使用
//}
public static String downloadMedia(String mediaId, String savePath,String out,String type) {
String filePath = null;
AccessToken accessToken = WeixinUtil.getAccessToken(WechatUtil.appId,
WechatUtil.appSecret, false);
// 拼接请求地址
String requestUrl = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken.getToken())
.replace("MEDIA_ID", mediaId);
String returnstr="0";
BufferedInputStream bis = null;
FileOutputStream fos = null;
HttpsURLConnection conn = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
// URL url = new URL(null,requestUrl,new
// sun.net.www.protocol.https.Handler());
// URL url = new URL(requestUrl);
URL url = new URL(requestUrl);
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod("GET");
// 根据内容类型获取扩展名
// String fileExt = DloadImgUtil
// .getFileexpandedName(conn.getHeaderField("Content-Type"));
// 将mediaId作为文件名
filePath = savePath;
bis = new BufferedInputStream(conn.getInputStream());
fos = new FileOutputStream(new File(filePath));
byte[] buf = new byte[8096];
int size = 0;
while ((size = bis.read(buf)) != -1)
fos.write(buf, 0, size);
amr2mp3(savePath,out);
} catch (Exception e) {
returnstr="-1";
e.printStackTrace();
} finally {
// 释放资源
conn.disconnect();
try {
// 关闭流,释放资源
if (fos != null) {
fos.close();
}
if (bis != null) {
bis.close();
}
} catch (Exception e) {
e.getStackTrace();
}
}
return returnstr;
}
/**
* 将一个amr文件转换成mp3文件
* @param amrFile
* @param mp3File
* @throws IOException
* -i :指定输入文件-ar : 指定sampling rate(采样率),它的单位是HZ
* -ac:指定声道,1表示双声道,0表示单声道-ab:指定转换后的比特率
* @throws InterruptedException
*/
public static void amr2mp31(String amrFileName, String mp3FileName) throws IOException, InterruptedException {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(FFMPEG_PATH + " -i "+amrFileName+" -ar 8000 -ac 1 -y -ab 12.5k " + mp3FileName); //12.4
InputStream in = process.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
try {
String line = null;
while((line = br.readLine())!=null) {
// System.out.println(line);
}
while((line = br.readLine())!=null){
System.out.println("</ERROR>");
int exitValue =process.waitFor();
System.out.println("Process exitValue="+exitValue);
}
} finally {
//为了避免这里抛出的异常会覆盖上面抛出的异常,这里需要用捕获异常。
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
使用微信js-sdk上传语音并将语音下载到服务器相关推荐
- 微信JS图片上传与下载功能--微信JS系列文章(三)
概述 在前面的文章微信JS初始化-- 微信JS系列文章(一)中已经介绍了微信JS初始化的相关工作,接下来本文继续就微信JS的图片上传功能进行描述,供大家参考. 图片上传 $(function(){va ...
- 微信js sdk 授权上传头像下载代码片段和注意事项
/* * 描述:当前页授权 * @param url 例:index.html / 如果有参数,需加密index.html?id=1 */ 1.对需要运用js sdk的页面授权 get ...
- Vue使用微信录音并上传服务端
在微信公众号或者微信h5的网页开发中,会用到录音等功能,在微信里面使用微信录音会比较好一点,不用去设置ios和android的h5录音兼容性,并且h5的其他录音js文件可能不兼容微信浏览器等,所以vu ...
- 微信小程序上传阿里云视频文件流程及代码
为了微信小程序客服端实现自拍视频能够分享给多个好友,我们需要把小程序自拍的视频存储到服务器,而阿里云在性能和速度上比较不错,所以我们选择了阿里云作服务器. 第一步.微信小程序项目创建 1. 到http ...
- 微信公众号开发《四》调用微信JS-SDK实现上传手机图片到服务器
在这粘贴上三篇博文链接,方便大家查阅互相学习: 微信公众号开发<一>OAuth2.0网页授权认证获取用户的详细信息,实现自动登陆 微信公众号开发<二>发送模板消息实现消息业务实 ...
- 使用微信js sdk关于选择及上传图片至腾讯云COS
使用微信js sdk关于选择及上传图片至腾讯云COS 使用微信js sdk关于选择及上传图片至腾讯云COS 背景 名词 参考 效果图展示 开发步骤 1:概要步骤 2:上代码 结束: 使用微信js sd ...
- 微信js sdk 分享 失败 有时候好 有时候坏
微信js sdk 分享 失败 有时候好 有时候坏 用了一个www开头的域名 和一个xx.com的域名 两个在解析上有问题. 实践是www.xx.com的比较 稳定 转载于:https://www.c ...
- 微信JS SDK开放,前端开发者“鸡冻”了!
HTML5又一次逆袭了,其实之前微信也是有一些JS API的,比如分享.但这次一股脑开放了拍摄.录音.语音识别.二维码.地图.支付.分享.卡券等几十个API,这条消息不需宣传,瞬间就占满了HTML5从 ...
- 微信上传素材 java_java微信接口之四—上传素材
一.微信上传素材接口简介 1.请求:该请求是使用post提交地址为: https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=A ...
- 微信小程序上传图像或者文件到阿里云oss
在微信小程序中新建一个文件夹upFile,分别有三个js文件:base64.js.crypto.js.alioss.js base64.js文件内容,在alioss.js中被引用 var Base64 ...
最新文章
- 如何解决现有的问题——VBA课程第五次讨论2007年12月13日
- hdu3313 最大流找关键点,或者最短路找关键点.
- JVM调优:-Xms40M -Xmx60M 指定堆的最小、最大大小
- jacoco 源码分析 class字节码植入的冲突问题
- 2020年10月份Github上热门的开源项目
- php 继承 父类使用子类,PHP父类调用子类方法实例
- 您该选择PRINCE2 还是 PMP认证
- 全志android编译过程
- Python 操作谷歌浏览器
- python爬数据是什么意思-这python爬虫是什么意思?爬虫怎么抓取数据?
- 2022年G3锅炉水处理考试题库及模拟考试
- 给不给你升职,领导关心的是什么?
- 陀螺产业区块链第九季 | 如何用区块链搭建营销激励模型?
- 无线短距离通信-蓝牙与wifi(一)
- 利用Google Earth卫星图更新地形图地物
- 用项目管理思维做一个活动策划
- Linux——文件或目录的权限管理、网络管理、进程管理、服务管理的相关命令
- Sony微单相机alpha6000 wifi远程控制(1)
- 在买了38台件米家智能家居后,告诉你米家什么不值得买
- 【AM335x新品发布】 TI Sitara系列TL335x-EVM-S评估板,你知多少?
热门文章
- Unity烘焙官方建议
- 用例建模指南lt;二gt;
- 面试数据库知识点总结
- 2023年全国最新工会考试精选真题及答案41
- 回顾|领略云原生技术之美
- 计算机适合用mac吗,原神能用苹果电脑玩吗
- mysql免安装版linux_Linux下配置免安装版的MySQL
- 【react实战小项目:笔记】用React 16写了个订单页面
- Unity3D本地文件夹的创建、删除(Directory文件夹删除和单个文件删除)
- Python 微信公众号开发