zoukankan      html  css  js  c++  java
  • 微信小程序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;
    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。

    参照写法一(不建议,处理的返回数据必须为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', 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}`);
        });
      })
    }

     

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

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

    // 云函数入口文件
    const cloud = require('wx-server-sdk')
    var request = require('request')
    cloud.init()
    
    // 云函数入口函数
    exports.main = async(event, context) => {
      var isbn = event.isbn
      return new Promise((resolve, reject) => {
        request.get('http://isbn.szmesoft.com/ISBN/Query?ISBN=' + isbn, (error, response, body) => {
          if (error) {
            reject()
          } else {
            try {
              resolve(body)
            } catch (e) {
              reject()
            }
          }
        })
      })
    }

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

    // 云函数入口文件
    const cloud = require('wx-server-sdk')
    var request = require('request')
    cloud.init()
    
    // 云函数入口函数
    exports.main = async (event, context) => {
      //qz
      return new Promise((resolve, reject) => {
        request({
          url: event.URL,
          method: "POST",
          json: true,
          headers: {
            "content-type": "application/json",
            "token":event.token
          },
        }, function (error, response, body) {
          if (!error && response.statusCode == 200) {
            try {
              resolve(body)
            } catch (e) {
              reject()
            }
          }
        })
      })
    }

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

  • 相关阅读:
    717. 1比特与2比特字符
    697. 数组的度
    674. 最长连续递增序列
    665. 非递减数列
    661. 图片平滑器
    643. 子数组最大平均数 I
    plink计算两个SNP位点的连锁不平衡值(LD)
    GWAS群体分层校正,该选用多少个PCA
    PyCharm的安装和应用
    GWAS后续分析:多基因风险评分(Polygenic Risk Score)的计算
  • 原文地址:https://www.cnblogs.com/masterchd/p/9895636.html
Copyright © 2011-2022 走看看