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()
            }
          }
        })
      })
    }

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

  • 相关阅读:
    .net注册iis
    hdu 1081To The Max
    hdu 1312Red and Black
    hdu 1016Prime Ring Problem
    hdu 1159Common Subsequence
    hdu 1372Knight Moves
    hdu 1686Oulipo
    hdu 1241Oil Deposits
    hdu 1171Big Event in HDU
    hdu 4006The kth great number
  • 原文地址:https://www.cnblogs.com/masterchd/p/9895636.html
Copyright © 2011-2022 走看看