config:invalid url donmain 首先,這是一個很蛋疼很蛋疼的問題;相信你正在使用微信的某些操蛋的功能,來兩張圖;感受下症狀,我的需求是調用圖片庫和相機,調用其他的功能也會出現這個類似的情況
以上就是症狀,估計都挺崩潰的,如果你是第一次搞這些東西,並且沒人指導那簡直就是蛋疼,微信那幫孫子寫的文檔大家都是瞭解的 ,想當年我們搞個微信支付配置,按照微信的文檔全公司包括一個十年工作經驗的大哥都他媽沒看懂。。。後來就放棄了。。。
撤了半天犢子,我們今天的需求是:調用微信公衆號的相機和圖片庫,然後就給老子出了上面的異常。。。。。如何在公衆號裏面調用相機和圖片庫?
我們是在微信公衆號裏面開發
那麼不管你開發啥子,AppId 和 AppSecret你一定是需要的 ,然後下一步
我們打開微信的文檔看看,微信教我們如何上傳圖片。。。。。。接着來張截圖
或許跟我一樣有同樣的疑惑, 這他孃的是啥?關鍵信息都他媽必填
debug:true 這個東西我們勉強還能看懂
appId:這個就是我們微信公衆號的appId 可以接受
timestamp:時間戳
nonceStr:隨機字符串
signature:簽名
jsApiList:[] 你需要調用的 接口列表
以上幾個, 一臉懵逼的往下看,發現越看越看不懂了,這些東西到底怎麼組合使用了 ?到最後
我們發現有個demo,一陣竊喜
相信你已經下載下來看了一次了,但是如果相信大部分人是做前端的,而下載代碼一看。。。 我擦嘞,怎麼看不懂啊。。 神馬幺蛾子
貌似是後端的語言,註定這個項目必須前後端一起配合才行,我們打開我們熟悉的Java或PHP
Java代碼執行下,發現輸出的三個字段居然是我們需要的 ,來張圖看下
那麼還有個問題,在前端配置這些屬性了 還是後端生成了 ?顯然這些數據有千絲萬縷的關係,如果放在前端的話,是不可能的。。。 還有url 和 jsapi_ticket又是個神馬鬼?我們現在獲取這些數據需要,一個URL和一個jsapi_ticket
蛋疼了 。。這些數據我們需要在後臺生成,首先來段後臺代碼,獲取jsapi_ticket這個鬼東西 api的票,必須拿到票才能調用API,這個票怎麼獲取了?
1.第一步獲取access_token,附上代碼
/// 獲取 titet之前獲取token
public static String getAccessToken() {
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wechatAppID
+ "&secret=" + wechatAppSecret;
try {
URL object = new URL(requestUrl);
HttpURLConnection con = (HttpURLConnection) object.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("GET");
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream(), "utf-8");
wr.flush();
StringBuilder sb = new StringBuilder();
int HttpResult = con.getResponseCode();
if (HttpResult == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(sb.toString());
return data.getString("access_token");
} else {
System.out.println(con.getResponseMessage());
}
return null;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
我們把token值log下 ,到底token是個什麼樣子的 。。 返回7200表示正常
2.第二步通過token獲取jsapi_ticket ,也就是將上面的access_token解析出來,然後當做參數傳給下個接口,上代碼
public static String getTiteck() {
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + getAccessToken();
try {
URL object = new URL(url);
HttpURLConnection con = (HttpURLConnection) object.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("GET");
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream(), "utf-8");
wr.flush();
StringBuilder sb = new StringBuilder();
int HttpResult = con.getResponseCode();
if (HttpResult == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(sb.toString());
return data.getString("ticket");
} else {
System.out.println(con.getResponseMessage());
}
return null;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
上面的accessToken是上個方法的返回值,異常等鬼東西就不處理了,我相信鵝廠的服務器,一般不會出異常,同樣來個log
jsapi_ticket我們獲取到了,但是我們發現一個問題。。。。。很蛋疼的問題,這個接口有限制調用次數
每一天限制調用十萬次 ,但是這個jsapi_ticket 貨在7200秒(七千二百秒 沒打錯)內有效,好吧,這已經不是我們討論的範疇了,用戶量大了,都他媽扯犢子,每天把十萬次的調用量用完,公司早就發了,,,,(針對小公司,大公司我在此就不多說了自己知道處理,獲取這玩意保存起來判斷時效)
我們獲取到了這貨之貌似萬事大吉了,但是還差一個東西url,url哪裏來? 又他媽一臉懵逼了。。。。
好吧,不賣關子了。。直接貼上代碼吧
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script src="jquery-1.8.3.min.js"></script>
</head>
<body>
<div style="width: 500px;height: 500px;background-color: red;" id="div"> </div>
</body>
<script>
$(function() {
findWxConfigParam();
$("#div").on("click", function() {
var sourceType = [];
if(1 == 1) {
sourceType.push('album');
} else {
sourceType.push('camera');
}
wx.chooseImage({
count: 1,
sourceType: sourceType,
success: function(res) {
var localId = res.localIds;
alert(localId);
}
});
});
});
function findWxConfigParam() {
var url = "http://127.0.0.1/hb/wechat/getWXconfig.do";
var data = {
"url": location.href.split('#')[0]
};
$.ajax({
type: "post",
url: url,
async: true,
data: data,
dataType: "json",
success: function(data, textStatus, jqXHR) {
initWxConfig(data["obj"]);
}
})
};
function initWxConfig(data) {
wx.config({
debug: true,
appId: data["appId"],
timestamp: data["timestamp"],
nonceStr: data["noncestr"],
signature: data["signature"],
jsApiList: ['getLocation', 'checkJsApi',
'chooseImage',
'uploadImage',
'downloadImage',
'previewImage'
]
});
wx.ready(function() {});
wx.error(function(res) {
});
};
</script>
</html>
有以下幾個地方要注意,
第一個:微信API的版本
微信官方提出來的版本是1.2,但是這個版本能用,嚐鮮的人可以試下微信提供的版本
地址 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
第二個地方:就是url的值
就這樣寫,沒錯的 。。。
第三個地方:權限使用了哪些接口,這些東西微信有說明
這裏就不解釋了
說到這裏我們不難發現,調取微信的接口是這樣的,前端傳一個url過去然後,服務端加密處理得到指定的字符串給到前端,那麼到這裏了。。。 服務端代碼上了 。。 首先上簽名的代碼
不要懷疑,來自微信官方的代碼
public static String signString(String jsapi_ticket, String url,String nonce_str,String timestamp) {
Map<String, String> ret = sign(jsapi_ticket, url,nonce_str,timestamp);
return ret.get("signature");
}
public static Map<String, String> sign(String jsapi_ticket, String url,String nonce_str,String timestamp) {
Map<String, String> ret = new HashMap<String, String>();
String string1;
String signature = "";
//注意這裏參數名必須全部小寫,且必須有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
System.out.println(string1);
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
這是生成簽名的代碼,接口代碼如下
@RequestMapping(value = "/getWXconfig.do")
public void getWechat(String url,HttpServletRequest request, HttpServletResponse response) throws Exception {
BaseBean baseBean = new BaseBean();
try {
HashMap<String, Object> map = new HashMap<>();
String jsapi_ticket = WechatCode.getTiteck();
map.put("jsapi_ticket", jsapi_ticket);
String timestamp = "" + (new Date()).getTime();
map.put("timestamp", timestamp);
String noncestr = UUID.randomUUID().toString();
map.put("noncestr", noncestr);
map.put("url", url);
String signature = CheckUtil.signString(jsapi_ticket,url,noncestr,timestamp);
map.put("signature", signature);
String appId = PropertiesUtil.getUrlPropertiesValue("wechatAppID");
map.put("appId", appId);
logger.error(map);
baseBean.setObj(map);
baseBean.setMsg("獲取成功");
baseBean.setCode(BaseBean.CODE_OK);
} catch (Exception e) {
logger.warn(Common.getRequestParam(request));
logger.warn(Common.handle(e));
baseBean.setMsg(e.getLocalizedMessage());
}
String json = JSONObject.fromObject(baseBean).toString();
response.getOutputStream().write(json.getBytes("UTF-8"));}
這兩個方法上文都提到了。。。 這裏就不解釋了。。。。。。。。
或許到了這裏。。。 我們以爲萬事大吉了 ,結束收工了。。。
然而,並沒有。。。。。。 或許你還會有同樣的感受。。。。那就是
接下來纔是本篇日誌的精華部分 那就是配置域名
第一步。。。。。
第二步。。。。
需要將這個文件下載下來,上傳到服務器的zszc的這個目錄下。。。。 也就是騰訊確認你的服務器作用。。。。
你的調用微信的頁面必須在/tomcat/webapp/zszc這個目錄下
配置域名成功之後。。。。 over。。。 收工。。。。。。。。。。