欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-25 17:36:19
http + 加密 + 认证 + 完整性保护 = https,小程序考虑到信息安全的问题,选用了更为稳定安全的https 来进行信息传递。 https协议的主要作用可以分...

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

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

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

但是也有解决方案。

1.中继访问

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

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

拥有域名和云服务器

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

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

腾讯云上免费部署https

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

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

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

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

实现这种功能,显而易见,在服务器上部署一个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}`);

  });

 })

}

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。