微信小程序http连接访问解决方案的示例
http + 加密 + 认证 + 完整性保护 = https,小程序考虑到信息安全的问题,选用了更为稳定安全的https 来进行信息传递。
https协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
这就导致了许多好用的http api无法在小程序中被调用。
但是也有解决方案。
1.中继访问
中继访问有两种方式,一种需要自己拥有一个云服务和域名。
拥有域名和云服务器
域名完成备案之后下载证书
https指引教程如下------>
再讲域名解析到你的云服务器的ip。
这样子你的域名就是https的了,小程序可以访问你的服务器了,现在就开始在云服务上实现访问http api 服务
实际上只需要面向小程序和api server 做一个双面响应即可。
实现这种功能,显而易见,在服务器上部署一个web项目是最简单的实现方式:
我们以访问豆瓣图书api 为例:https://api.douban.com/v2/book/isbn/
豆瓣api虽然是https的,但是来自小程序的访问是被禁止的。下面代码同样适用于http 连接
java代码:
这个是 通用代码 ,无论是访问什么api
package dataservice; import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.io.outputstreamwriter; import java.io.printwriter; import java.net.httpurlconnection; import java.net.url; import java.net.urlconnection; import java.sql.resultset; import com.google.gson.gson; /* * author:陈浩东 * qq:1025584691 */ public class doubanbook { //豆瓣接口实现 public static string dopost(string url, string params, integer conntimeout, integer readtimeout, string contenttype) { printwriter out = null; bufferedreader in = null; string result = ""; try { url realurl = new url(url); // 打开和url之间的连接,根据url urlconnection conn = realurl.openconnection(); // 设置通用的请求属性 conn.setrequestproperty("accept", "*/*"); conn.setrequestproperty("connection", "keep-alive"); conn.setrequestproperty("user-agent", "mozilla/4.0 (compatible; msie 6.0; windows nt 5.1;sv1)"); conn.setrequestproperty("content-type", contenttype == null? "application/json" : contenttype); // 发送post请求必须设置如下两行 conn.setdooutput(true); conn.setdoinput(true); // 设置请求超时时间和读取超时时间 conn.setconnecttimeout(conntimeout == null ? 180 : conntimeout); conn.setreadtimeout(readtimeout == null ? 180 : readtimeout); // 获取urlconnection对象对应的输出流,设置utf-8编码 out = new printwriter(new outputstreamwriter(conn.getoutputstream(), "utf-8")); // 发送请求参数 out.print(params); // flush输出流的缓冲 out.flush(); // 定义bufferedreader输入流来读取url的响应,设置utf-8编码 in = new bufferedreader(new inputstreamreader(conn.getinputstream(), "utf-8")); string line; while ((line = in.readline()) != null) result += line; } catch (exception e) { e.printstacktrace(); result = null; } //使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (ioexception ex) { ex.printstacktrace(); } } return result; } }
根据访问不同的api,只需要修改servlet的写法就可以:
servlet:
package servlet; import java.io.ioexception; import java.io.writer; import java.util.hashmap; import java.util.map; import javax.servlet.servletexception; import javax.servlet.annotation.webservlet; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import com.google.gson.gson; import dataservice.doubanbook; /** * servlet implementation class doubanbook */ @webservlet("/doubanbook") public class doubanbook extends httpservlet { protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { request.setcharacterencoding("utf-8"); response.setcontenttype("text/html;charset=utf-8"); response.setheader("access-control-allow-origin", "*"); response.setheader("access-control-allow-methods", "get,post"); string isbn = request.getparameter("isbn")==null?"no":request.getparameter("isbn"); string sshpwd = request.getparameter("ssh_secret")==null?"no":request.getparameter("ssh_secret"); system.out.println(sshpwd); system.out.println(isbn); map<string, object> result = new hashmap<string, object>(); string json = new gson().tojson(result); writer out = response.getwriter(); out.write(doubanbook.dopost("https://api.douban.com/v2/book/isbn/"+isbn, null, null, null, null)); out.flush(); } protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { // todo auto-generated method stub doget(request, response); } }
同样,你也可以用python,php等语言来实现中继访问这个功能。
无域名和云服务器
对于个人开发者来说,尤其是学生来说,又是是没有条件购买长时间的云服务器的,这个时候我们如果是开发小程序的话,可以用他们提供的空间。
使用微信小程序的云开发能力,node.js 函数,用js 实现服务端的响应,访问非https api。
参照写法一:
云函数调用方式访问api
const cloud = require('wx-server-sdk') cloud.init() // 云函数入口函数 exports.main = async (event, context) => { console.log(event) console.log(context) return new promise((resolve, reject) => { var url = event.url;//前端小程序传的data var https = require('https'); https.get(url, function (res) { var size = 0; var chunks = []; res.on('data', function (chunk) { size += chunk.length; chunks.push(chunk); }); res.on('end', function () { var data = buffer.concat(chunks, size).tostring(); console.log(data) resolve(json.parse(data)) }); }).on('error', (e) => { console.log(`url:${url} error: ${e.message}`); }); }) }
不知道什么原因,云函数我感觉并不是很稳定,建议有条件的还是用自己的服务器来实现吧。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。