微信小程序http连接访问解决方案

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

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

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

但是也有解决方案。

1.中继访问

 

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

拥有域名和云服务器

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

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

腾讯云上免费部署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;
 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 class DouBanBook {
    //豆瓣接口实现
    static String doPost(String url,String params,Integer connTimeout,Integer readTimeout,String contentType)
    {
        PrintWriter out = null;
        BufferedReader in = ;
        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();
     
             设置请求超时时间和读取超时时间
            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();
            }
        }
        return result;
    }
}

 

  

  根据访问不同的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 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 =  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()
 
 云函数入口函数
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',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码访问并获得图书信息的接口

 云函数入口文件
const cloud = require('wx-server-sdk'var request = require('request')
cloud.init()

 云函数入口函数
exports.main = async(event,1)"> {
  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()
        }
      }
    })
  })
}

 

 

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

 

相关文章

概述 消息能力是小程序能力中的重要组成,我们为开发者提供了...
判断H5页面环境在微信中还是小程序中 用小程序提供的wx.mini...
wx.reLaunch和wx.navigateTo,wx.navigateTo的区别 2019-03-...
微信小程序如何从数组里取值_微信小程序 传值取值的几种方法...
H5项目接入微信授权登录,通过 UA 区分微信还是普通浏览器:...
微信小程序获取data-xx=&quot;&quot;属性的值,自定...