小程序怎样链接上服务器,微信小程序http连接访问解决方案

本文介绍了微信小程序因安全原因采用HTTPS协议,但导致无法直接调用HTTP API。解决方案包括中继访问,即通过自有的云服务器或微信小程序的云开发能力实现数据转发。文中提供了Java、Python和Node.js的示例代码,帮助开发者解决此类问题。

HTTP + 加密 + 认证 + 完整性保护 = HTTPS,小程序考虑到信息安全的问题,选用了更为稳定安全的https 来进行信息传递。

HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

这就导致了许多好用的http  API无法在小程序中被调用。

但是也有解决方案。

1.中继访问

9d69f5a99c8820620ff3c3367d09bd8d.png

中继访问有两种方式,一种需要自己拥有一个云服务和域名。

拥有域名和云服务器

域名完成备案之后下载证书

https指引教程如下------>

再讲域名解析到你的云服务器的IP。

这样子你的域名就是https的了,小程序可以访问你的服务器了,现在就开始在云服务上实现访问http API 服务

实际上只需要面向小程序和API Server 做一个双面响应即可。

a25b0e9575b61cb135114b23b6626719.png

实现这种功能,显而易见,在服务器上部署一个Web项目是最简单的实现方式:

我们以访问豆瓣图书API 为例:https://api.douban.com/v2/book/isbn/

豆瓣API虽然是https的,但是来自小程序的访问是被禁止的。下面代码同样适用于http 连接

Java代码:

这个是通用代码,无论是访问什么API

packageDataService;importjava.io.BufferedReader;java.io.IOException;java.io.InputStream;java.io.InputStreamReader;java.io.OutputStreamWriter;java.io.PrintWriter;java.net.HttpURLConnection;java.net.URL;java.net.URLConnection;java.sql.ResultSet;com.google.gson.Gson;/** Author:陈浩东

* QQ:1025584691*/

public classDouBanBook {//豆瓣接口实现

staticString doPost(String url,String params,Integer connTimeout,Integer readTimeout,String contentType)

{

PrintWriter out= null;

BufferedReader in= ;

String result= "";try{

URL realUrl= newURL(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();设置请求超时时间和读取超时时间

conn.setConnectTimeout(connTimeout == null ? 180: connTimeout);

conn.setReadTimeout(readTimeout== : 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(),1)">));

String line;

while ((line = in.readLine()) != )

result+=line;

}catch(Exception e)

{

e.printStackTrace();

result= ;

}使用finally块来关闭输出流、输入流

finally{{if (out != )

{

out.close();

}if (in != )

{

in.close();

}

}(IOException ex)

{

ex.printStackTrace();

}

}returnresult;

}

}

根据访问不同的API,只需要修改Servlet的写法就可以:

Servlet:

Servlet;java.io.Writer;java.util.HashMap;java.util.Map;javax.servlet.ServletException;javax.servlet.annotation.WebServlet;javax.servlet.http.HttpServlet;javax.servlet.http.HttpServletRequest;javax.servlet.http.HttpServletResponse;DataService.DouBanBook;/*** Servlet implementation class doubanbook*/@WebServlet("/doubanbook")class doubanbook extendsHttpServlet {protected void doGet(HttpServletRequest request,HttpServletResponse response) throwsServletException,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 result = new HashMap();

String json= Gson().toJson(result);

Writer out=response.getWriter();

out.write(DouBanBook.doPost("https://api.douban.com/v2/book/isbn/"+isbn,null,1)">));

out.flush();

}

void doPost(HttpServletRequest request,IOException {

TODO Auto-generated method stub

doGet(request,response);

}

}

同样,你也可以用Python,PHP等语言来实现中继访问这个功能。

无域名和云服务器

对于个人开发者来说,尤其是学生来说,又是是没有条件购买长时间的云服务器的,这个时候我们如果是开发小程序的话,可以用他们提供的空间。

使用微信小程序的云开发能力,Node.js 函数,用js 实现服务端的响应,访问非https API。

参照写法一(不建议,处理的返回数据必须为JSON才可以):

云函数调用方式访问API

const cloud = require('wx-server-sdk')

cloud.init(){

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',1)"> (chunk) {

size +=chunk.length;

chunks.push(chunk);

});

res.on('end',1)"> () {

var data =Buffer.concat(chunks,size).toString();

console.log(data)

resolve(JSON.parse(data))

});

}).on('error',(e) =>{

console.log(`url:${url} error: ${e.message}`);

});

})

}

参考写法二,需要导入http包,返回的数据在小程序端需要用JSON.parse(res.result) 转为JSON数据

这个api是根据isbn码访问并获得图书信息的接口

var request = require('request')

cloud.init()var isbn =event.isbn{

request.get('http://isbn.szmesoft.com/ISBN/Query?ISBN=' + isbn,(error,response,body) =>{if(error) {

reject()

}else{{

resolve(body)

}(e) {

reject()

}

}

})

})

}

参照写法三:要在云函数开始调用的部分添加参数,且只适合POST方式,把参数全部用&连接到URL上

qz

{

request({

url: event.URL,method:"POST",json::event.token

},},1)"> (error,body) {if (!error && response.statusCode == 200) {(e) {

reject()

}

}

})

})

}

不知道什么原因,云函数我感觉并不是很稳定,建议有条件的还是用自己的服务器来实现吧。

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

为什么需要websocket? 传统的实时交互的游戏,或服务器主动发送消息的行为(如推送服务),如果想做在微信上,可能你会使用轮询的方式进行,不过这太消耗资源,大量的请求也加重了服务器的负担,而且延迟问题比较严重。如果是自己开发的app,为了解决这些问题,很多团队会自建socket,使用tcp长链接、自定协议的方式与服务器进行相对实时的数据交互。有能力的团队,采用这种方式自然没什么大问题。不过小团队可能就要花费很多时间去调试,要解决很多难题,这个在成本上就划不来。 H5引入了webSocket来解决网页端的长链接问题,而微信小程序也支持websocket。这是一个非常重要的特性,所以本系列的文章会专门拿出一篇来讨论websocket。 webSocket本质上也是TCP连接,它提供全双工的数据传输。一方面可以避免轮询带来的连接频繁建立与断开的性能损耗,另一方面数据可以是比较实时的进行双向传输(因为是长链接),而且WebSocket允许跨域通信(这里有个潜在的跨域安全的问题,得靠服务端来解决)。目前除IE外的浏览器已经对webSocket支持得很好了,微信小程序再推一把之后,它会变得更加流行。 我们来设计一个新的demo,一个比较有趣的小游戏,多人版扫雷,准确地讲,多人版挖黄金。 游戏规则是这样的:把雷换成金子,挖到金子加一分,每人轮流一次(A挖完轮到B,B挖完A才能再点击),点中金子就算你的,也不会炸,游戏继续,直到把场上所有的金子都挖完游戏才结束。跟扫雷一样,数字也是表示周边有几个金子,然后用户根据场上已经翻出来的数字来猜哪一格可能有金子。 这种交互的游戏难点在于,用户的点击操作都要传到服务器上,而且服务器要实时的推送到其它玩家的应用上。另外用户自己也要接收对方操作时实时传过来的数据,这样才不至于重复点中同一个格子。简单讲,就是你要上报操作给服务器,而服务器也要实时给你推消息。为了简化整个模型,我们规定玩家必须轮流来点击,玩家A点完后,才能轮到玩家B,玩家B操作完,玩家A才能点。 我们分几步来实现这个功能。 一、实现思路 1、第一步,我们要先生成扫雷的地图场景 这个算法比较简单,简述一下。随机取某行某列就可以定位一个格子,标记成金子(-1表示金子)。mimeCnt表示要生成的金子的数量,用同样的方式循环标记mimeCnt个随机格子。生成完后,再用一个循环去扫描这些-1的格子,把它周边的格子都加1,当然必须是非金子的格子才加1。代码放在这里。 其中increaseArround用来把这格金子周边的格子都加1,实现也比较简单: 执行genMimeArr(),随机生成结果如下: -1表示金子。看了下貌似没什么问题。接下去,我们就要接入webSocket了。 (这个是js版本的,其实生成地图场景的工作是在后台生成,这个js版本只是一个演示,不过算法是一样的。) 2、我们需要一个支持webSocket的服务端 本例子中,我们使用python的tornado框架来实现(tornado提供了tornado.websocket模块)。当然读者也可以使用socket.io,专为webSocket设计的js语言的服务端,用起来非常简单,它也对不支持webSocket的浏览器提供了兼容(flash或comet实现)。 笔者本人比较喜欢使用tornado,做了几年后台开发,使用最多的框架之一的就是它,NIO模型,而且非常轻量级,同样的rps,java可能需要700-800M的内存,tornado只要30-40M,所以在一台4G内存的机子上可以跑上百个tornado服务,而java,对不起,只能跑3个虚拟机。微服务的时代,这一点对小公司很重要。当然如果读者本人对java比较熟悉的话,也可以选择netty框架尝试一下。 webSocket用tornado的另一个好处是,它可以在同一个服务(端口)上同时支持webSocket及http两种协议。tornado的官方demo代码中展示了怎么实现同时使用两种协议。在本游戏中,可以这么用:用户进入首页,用http协议去拉取当前的房间号及数据。因为首页是打开最多的,进了首页的用户不一定会玩游戏。所以首页还没必要建立webSocket链接,webSocket链接主要用来解决频繁请求及推送的操作。首页只有一个请求操作。选了房间号后,进去下一个游戏页面再开始建立webSocket链接。 3、客户端 使用微信小程序开发工具,直接连接是会报域名安全错误的,因为工具内部做了限制,对安全域名才会允许连接。所以同样的,这里我们也继续改下工具的源码,把相关的行改掉就行修改方式如下: 找到asdebug.js的这一行,把它改成: if(false)即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值