惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
Google Online Security Blog
Google Online Security Blog
Hugging Face - Blog
Hugging Face - Blog
L
LINUX DO - 热门话题
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
D
Docker
C
Cyber Attacks, Cyber Crime and Cyber Security
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
T
Tenable Blog
P
Privacy International News Feed
Google DeepMind News
Google DeepMind News
小众软件
小众软件
Cisco Talos Blog
Cisco Talos Blog
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
The Hacker News
The Hacker News
Project Zero
Project Zero
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
Jina AI
Jina AI
Cyberwarzone
Cyberwarzone
The Register - Security
The Register - Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Vercel News
Vercel News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
MongoDB | Blog
MongoDB | Blog
U
Unit 42
Scott Helme
Scott Helme
A
About on SuperTechFans
WordPress大学
WordPress大学
F
Fortinet All Blogs
大猫的无限游戏
大猫的无限游戏
G
GRAHAM CLULEY
Latest news
Latest news
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Schneier on Security

博客园 - 五味果

TextBoxFor控件的扩展---Bootstrap在mvc上的应用 Dapper Vs Dbentry 外地手机号码,请在号码前加拨0 Sql 2012 远程数据库连接 DbEntry在Vs2012里的配置 终点,也是新的起点! 天气预报数据查询接口 关于浏览器账号的一个愿望 关于移动,联通,电信的区分。 - 五味果 - 博客园 被#号折腾了。 Orm 请别让数据库中的默认值形同虚设!! 利用反射,泛型,静态方法快速获取表单值到Model。 subsonic sqlite 路径问题 - 五味果 ORM是工具,工具是用来提高开发速度的。 基于XML的后台管理系统--设想 项模板的使用--提高编程速度 C#开发编码规范 基于Jquery的内容显示模块 - 五味果 - 博客园 IIS7下运行Access+Asp的解决方法
.net Core 调用微信Jsapi接口,H5解析二维码
五味果 · 2018-11-06 · via 博客园 - 五味果

项目里需要用到扫描二维码,自己实现,不会。

找到了两种解决方案:

  1. 通过reqrcode.js,这是一个前端解析二维码内容的js库。如果二维码比较清晰,用这种效果也不错
  2. 调用微信扫一扫功能,这种效果很好。但是调试接口超级麻烦。

具体实现:前端代码(vue)(前端用到 vux

<template>
<div class="main">
  <group title="打印机参数" label-width="5.5em">
      <x-input title="名称" placeholder="输入打印机名称" v-model="model.name" :required="true" @on-change="check" ref="name"></x-input>
      <x-input title="MAC地址" placeholder="输入MAC地址" v-model="model.mac"  @on-change="check" ref="mac">
        <a slot="right-full-height" class="scan" @click="scan()" title="扫码"><x-icon type="android-expand" size="32"></x-icon></a>
      </x-input>
      <cell title="城市" :value="city"></cell>
      <cell title="经纬度" :value="location"></cell>
  </group>
  <iframe id="geoPage" width=0 height=0 frameborder=0  style="display:none;" scrolling="no"  src="https://apis.map.qq.com/tools/geolocation?key=212121U3F2Q&referer=3Dprint"></iframe>
  <x-button type="primary" @click.native="add()" :disabled.sync="disabled"> 添加打印机</x-button>
  <input type="file" accept="image/*" capture="camera" @change="show($event)" v-show="false" ref="file">
</div>
</template>
<script>
import {Group, XInput, XButton, Alert, Range, XSwitch, Cell, InlineXSwitch, ChinaAddressV4Data} from 'vux'
export default {
  components: {Group, XInput, XButton, Alert, Range, XSwitch, Cell, InlineXSwitch, ChinaAddressV4Data},
  data () {
    return {
      addressData: ChinaAddressV4Data,
      disabled: true,
      city: '',
      location: '',
      sys: false, // 扫一扫调用
      model: {
        name: '',
        mac: '',
        status: false,
        citys: [],
        city: '',
        address: '',
        memory: '',
        temperature: 0,
        modelName: '',
        location: '',
        ver: '',
        step: 0,
        plantTemperature: '',
        userId: 0
      }
    }
  },
  mounted () {
    // this.getLocation()
    let that = this
    window.addEventListener('message', function (event) {  
      var loc = event.data
      if (loc) {
        that.city = loc.nation + ' ' + loc.province + ' ' + loc.city
        that.location = loc.lat + ' , ' + loc.lng
        that.model.address = that.city
        that.model.location = that.location
      }
      console.log('location', loc)
    }, false)
    this.initConifig()
  },
  methods: {
    add () {
      let that = this
      this.model.userId = sessionStorage["userId"]
      this.model.status = this.model.status ? 1 : 0
      this.model.city = this.model.citys.join()
     // console.log(this.model.city)
      console.log(this.$store.state.user)
      this.Ajax.post('/api/services/app/Print/Create', this.model).then(function (result) {
        // console.log(that.model)
        if (result.success) {
          that.go('/user/prints')
        } else {
          that.$vux.toast.show({text: result.error.message, type: 'cancel'})
        }
      })
    },
    check () {
      this.disabled = !(this.model.name !== '' && this.model.mac !== '')
    },
    initConifig () {
      let that = this
      /* global wx */
      this.Ajax.get('/WX/GetConfig?url=' + location.href).then((r) => {
        let data = r.result
        console.log(data)
        wx.config({
          debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
          appId: data.appId, // 必填,公众号的唯一标识
          timestamp: data.timestamp, // 必填,生成签名的时间戳
          nonceStr: data.noncestr, // 必填,生成签名的随机串
          signature: data.signature, // 必填,签名,见附录1
          jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口2
        })
        that.sys = true
        wx.error((r) => {
          console.log(r)
          that.sys = false
          alert('微信调用异常:' + r.errMsg)
        })
      })
    },
    wxScan () {
      let that = this
       /* global wx */
      wx.scanQRCode({
        needResult: 1,
        desc: 'scanQRCode desc',
        success: (r) => {
          console.log(r)
          let msg = r.resultStr
          if (msg.length === 29) {
            let mac = msg.substring(17, 29)
            let arrs = []
            console.log(mac)
            for (let i = 0; i < 6; i++) {
              arrs.push(mac.substring(i * 2, i * 2 + 2))
            }
            that.model.mac = arrs.join(':')
            console.log(msg, that.model.mac)
          } else {
            that.$vux.toast.show({text: 'mac解析失败:' + msg, type: 'cancel'})
          }
        }
      })
    },
    scan () {
      if (this.sys) {
        this.wxScan()
      } else {
        this.$refs.file.click()
      }
    },
    go (link) {
      this.$router.push({path: link})
    },
    show (send) {
      // var file = console.log(send)
      /* global qrcode */
      let file = send.target.files[0]
      qrcode.decode(this.getUrl(file))
      var that = this
      qrcode.callback = function (msg) {
        if (msg.length === 29) {
          let mac = msg.substring(17, 29)
          let arrs = []
          console.log(mac)
          for (let i = 0; i < 6; i++) {
            arrs.push(mac.substring(i * 2, i * 2 + 2))
          }
          that.model.mac = arrs.join(':')
          console.log(msg, that.model.mac)
        } else {
          that.$vux.toast.show({text: 'mac解析失败:' + msg, type: 'cancel'})
        }
      }
    },
    getUrl (file) {
      let url = null
      if (window.createObjectURL !== undefined) {
        url = window.createObjectURL(file)
      } else if (window.URL !== undefined) {
        url = window.URL.createObjectURL(file)
      } else if (window.webkitURL !== undefined) {
        url = window.webkitURL.createObjectURL(file)
      }
      return url
    },
    getLocation () {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (p) {
          console.log(p)
        })
      } else {
        alert('不支持定位')
      }
    }
  }
}
</script>
<style  scoped>
.ptitle{ background: #efeff4;padding: 10px 20px; font-size: 16px; font-weight: bold; border-bottom: #d8d8dd;}
a.add:hover{ color: #4086ff;fill: #4086ff;cursor: pointer;}
.main{padding: 0 10px;}
a.scan{ fill: #4086ff; cursor: pointer;}
</style>

通用.net core 微信授权获取方法。

using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;

namespace PrintServe.Web.Host.Core
{
    public static class WXApi
    {
        /// <summary>
        /// 过期时间
        /// </summary>
        public static DateTime OutDateTime { get; set; }
        /// <summary>
        /// 凭据
        /// </summary>
        public static string Token { get; set; }
        /// <summary>
        /// 船票
        /// </summary>
        public static string Ticket { get; set; }
        /// <summary>
        /// 获取微信api接口船票
        /// </summary>
        /// <param name="url">请求页面地址</param>
        /// <param name="appId">开发者Id</param>
        /// <param name="secret">开发者密码</param>
        /// <returns></returns>
        public static dynamic  GetConfig(string url,string appId,string secret)
        {
            var timestamp = CreatenTimestamp();
            var noncestr = CreatenNonce_str();
            var ticket = Ticket;
            if (DateTime.Now > OutDateTime)
            {
                var token = GetToken(appId, secret);
                if (!string.IsNullOrEmpty(token))
                {
                    OutDateTime = DateTime.Now.AddMinutes(90);
                    Token = token;
                    Ticket = GetTickect(Token);
                    ticket = Ticket;
                }
            }
            var signature = GetSignature(ticket, noncestr, timestamp, url, out var str);
            return new
            {
                ticket,
                appId,
                url,
                timestamp,
                noncestr,
                signature,
                str
            };
        }
        /// <summary>
        /// 获取凭据
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public static string GetToken(string appid,string secret)
        {
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}",appid,secret);
            var client = new HttpClient();
            var result = client.GetAsync(url).Result;
            if (!result.IsSuccessStatusCode) return string.Empty;
            var jsTicket = result.Content.ReadAsStringAsync().Result;
            var v = JsonConvert.DeserializeObject<dynamic>(jsTicket);
            return v.access_token.ToString();
        }
        /// <summary>
        /// 获取船票
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static string GetTickect(string token)
        {
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", token);
            var client = new HttpClient();
            var result = client.GetAsync(url).Result;
            if (!result.IsSuccessStatusCode) return string.Empty;
            var jsTicket = result.Content.ReadAsStringAsync().Result;
            var v = JsonConvert.DeserializeObject<dynamic>(jsTicket);
            return v.ticket.ToString();
        }
        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <returns></returns>
        public static long CreatenTimestamp()
        {
            return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }

        ///  <summary>
        ///  签名算法
        /// 本代码来自开源微信SDK项目:https://github.com/night-king/weixinSDK
        ///  </summary>
        ///  <param name="jsapi_ticket">jsapi_ticket</param>
        ///  <param name="noncestr">随机字符串(必须与wx.config中的nonceStr相同)</param>
        ///  <param name="timestamp">时间戳(必须与wx.config中的timestamp相同)</param>
        ///  <param name="url">当前网页的URL,不包含#及其后面部分(必须是调用JS接口页面的完整URL)</param>
        /// <param name="string1"></param>
        /// <returns></returns>
        public static string GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url, out string string1)
        {
            url = url.Split('#')[0];
            var string1Builder = new StringBuilder();
            string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
                .Append("noncestr=").Append(noncestr).Append("&")
                .Append("timestamp=").Append(timestamp).Append("&")
                .Append("url=").Append(url);
            string1 = string1Builder.ToString();
            return Sha1(string1);
        }
        /// <summary>
        /// 创建随机字符串
        ///本代码来自开源微信SDK项目:https://github.com/night-king/weixinSDK
        /// </summary>
        /// <returns></returns>
        public static string CreatenNonce_str()
        {
            var strs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
            Random r = new Random();
            var sb = new StringBuilder();
            var length = strs.Length;
            for (int i = 0; i < 15; i++)
            {
                sb.Append(strs[r.Next(length - 1)]);
            }
            return sb.ToString();
        }
        /// <summary>
        /// HMAC-SHA1加密算法
        /// </summary>
        /// <param name="str">加密字符串</param>
        /// <returns></returns>
        public static string Sha1(string str)
        {
            var sha1 = SHA1.Create();
            var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(str));
            string byte2String = string.Empty;
            foreach (var t in hash)
            {
                byte2String += t.ToString("x2");
            }
            return byte2String;
        }
    }
}

controller调用

using System;
using Abp.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using PrintServe.Configuration;
using PrintServe.Web.Host.Core;

namespace PrintServe.Web.Host.Controllers
{
    public class WXController : AbpController
    {
        private readonly IConfigurationRoot _configuration;
        public WXController(IHostingEnvironment env)
        {
            _configuration = env.GetAppConfiguration();
        }
        public dynamic GetConfig(string url)
        {
            var appId = _configuration["wx:appid"];
            var secret = _configuration["wx:secret"];
//            Logger.Error("出现异常");
            return WXApi.GetConfig(url,appId,secret);
        }
        [HttpGet]
        public string Test(string input)
        {
            return WXApi.Sha1(input);
        }
       
    }
}

在主页面要添加微信接口js调用

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
    <title>3D打印</title>
    <script src="./static/js/reqrcode.js"></script>
    <!-- <script src="./static/js/vconsole.min.js"></script> -->
    <!-- <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> -->
    <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>
  </head>
  <body>
    <div id="app-box"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

调用微信api接口:

1:Ip,和域名都要加到微信公众平台里,缺一不可,在这里被坑了很久。

设置域名,一个月只能设置3次,要慎重。

2:调试时候,最好在开发机器上用花生壳绑定个域名,以便开发。本地没有域名,不能调试。可以下载微信开发者工具,进行调试,错误提示比较清晰。

微信开发者工具地址:地址

参考文章:

微信公众号开发之调起微信扫一扫接口

微信公众号开发:调用微信扫一扫功能

qrcode.js的识别解析二维码图片和生成二维码图片