博客 (117)

官方 Demo

WeUI:https://weui.io/

weui.js:https://weui.io/weui.js/


开发文档

WeUI:https://github.com/Tencent/weui/wiki

weui.js:https://github.com/Tencent/weui.js/blob/master/docs/README.md

WeUI for 小程序:https://github.com/Tencent/weui-wxss


引入

① <head /> 中加入:

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0" />

② 引用样式:(请更改地址中的版本号,参开发文档

<link href="https://res.wx.qq.com/t/wx_fed/weui-source/res/2.5.16/weui.min.css" rel="stylesheet" />

③ (可选)引用脚本:(请将下方链接中的版本号替换为最新)

<script src="https://res.wx.qq.com/t/wx_fed/weui.js/res/1.2.17/weui.min.js"></script>


经验

  • 搜索框的 <form /> 中不加 action 则键盘中显示灰色“换行”键,加入 action 则键盘中显示蓝色“搜索”键

xoyozo 8 年前
8,323
  1. 在 NuGet 中安装 Microsoft.AspNetCore.Session 和 Newtonsoft.Json

  2. 打开 Startup.cs,在 ConfigureServices 方法中加入(视情况配置相关属性)

    services.AddSession(options =>
    {
        // 设置了一个较短的时间,方便测试
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.CookieHttpOnly = true;
    });
  3. 在 Configure 方法中加入

    app.UseSession();
  4. 添加 Extensions 文件夹并添加类 SessionExtensions.cs

    using Microsoft.AspNetCore.Http;
    using Newtonsoft.Json;
    
    public static class SessionExtensions
    {
        public static void Set<T>(this ISession session, string key, T value)
        {
            session.SetString(key, JsonConvert.SerializeObject(value));
        }
    
        public static T Get<T>(this ISession session, string key)
        {
            var value = session.GetString(key);
            return value == null ? default(T) :
                                  JsonConvert.DeserializeObject<T>(value);
        }
    }
  5. 使用方法

    HttpContext.Session.Set("abc", 123);
    var v1 = HttpContext.Session.Get<int>("abc");
    HttpContext.Session.Remove("abc");
    var v2 = HttpContext.Session.Get<int>("abc");
    // v1 = 123, v2 = 0
xoyozo 8 年前
5,283

在本教程中,我解释了如何使用 jQuery 和 ASP.NET 发送跨域 AJAX 请求,PHP 开发者请参考此文

跨域 AJAX 请求有两种方式:

1). 使用 JSONP

2). 使用 CORS(跨源资源共享)

1). 使用 JSONP

我们可以使用 JSONP 发送跨域 AJAX 请求。下面是简单的 JSONP 请求:

$.ajax({
    url : "http://xoyozo.net/cross-domain-cors/jsonp.aspx",
    dataType:"jsonp",
    jsonp:"mycallback",
    success:function(data)
    {
        alert("Name:"+data.name+"nage:"+data.age+"nlocation:"+data.location);
    }
});

jsonp.aspx 响应是:

mycallback({"name": "Ravishanker", "age": 32, "location": "India"})

当 JSONP 请求成功时,调用 mycallback 函数。

这能在所有浏览器中正常运行,但问题是:JSONP 只支持 GET 方法,不支持 POST 方法。

2). 使用 CORS(跨源资源共享)

出于安全考虑,浏览器不允许跨域 AJAX 请求。仅当服务器指定相同的源安全策略时,才允许跨域请求。常见的异常警告:

You can not send Cross Domain AJAX requests: 

XMLHttpRequest cannot load. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin is therefore not allowed access.

阅读更多关于跨源资源共享(CORS):Wiki

要启用 CORS,您需要在服务器中指定以下 HTTP 标头。

Access-Control-Allow-Origin &ndash; 允许跨域请求的域的名称。 * 表示允许所有域。

Access-Control-Allow-Methods &ndash; 在请求期间可以使用 HTTP 方法的列表。

Access-Control-Allow-Headers &ndash; 可以在请求期间使用 HTTP 头列表。

在 ASP.NET 中,您可以使用以下代码设置标头:

Response.AddHeader("Access-Control-Allow-Origin", "*");
Response.AddHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Content-Range, Content-Disposition, Content-Description");

CORS 在所有最新的浏览器中正常工作,但不支持 IE8 和 IE9,异常:

You can not send Cross Domain AJAX requests: No Transport

IE8、IE9 使用 window.XDomainRequest 处理 AJAX 请求。我们可以使用这个 jQuery 插件:

https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest

为了在 IE 中使用 XDomainRequest,请求必须是:

a). GET 或 POST

    数据必须以 Content-Type 为 text/plain 的方式发送

b). HTTP 或 HTTPS

    协议必须与调用页面相同

c). 异步

具体步骤:

第一步:在 <head> 中添加脚本

<script type='text/javascript' src="http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest.min.js"></script>

第二步:在 $.ajax 请求中设置 contentType 值 text/plain

var contentType ="application/x-www-form-urlencoded; charset=utf-8";
 
if(window.XDomainRequest) // for IE8,IE9
    contentType = "text/plain";
 
$.ajax({
    url: "http://xoyozo.net/cross-domain-cors/post.aspx",
    data: "name=Ravi&age=12",
    type: "POST",
    dataType: "json",   
    contentType: contentType,    
    success: function(data)
    {
       alert("Data from Server" + JSON.stringify(data));
    },
    error: function(jqXHR, textStatus, errorThrown)
    {
       alert("You can not send Cross Domain AJAX requests: " + errorThrown);
    }
});

post.aspx 源码:

Response.AddHeader("Access-Control-Allow-Origin", "*");
Response.AddHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Content-Range, Content-Disposition, Content-Description");

NameValueCollection nvc = new NameValueCollection();
// nvc.Add(Request.QueryString);
nvc.Add(Request.Form);
if (nvc.Count == 0)
{
  string data = System.Text.Encoding.Default.GetString(Request.BinaryRead(Request.TotalBytes));
  nvc = HttpUtility.ParseQueryString(data);
}

string name = nvc["name"];
int age = Convert.ToInt32(nvc["age"]);

 

xoyozo 9 年前
7,077

UTC(世界协调时间)和 GMT(格林尼治标准时间)都与英国伦敦的本地时间相同。北京是东八区,即 UTC+8 或 GMT+0800

时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

翻译成程序员语言就是指当前的本地时间与 1970-1-1 0:00:00 UTC 时间换算的本地时间相差的秒数
或者当前的 UTC 时间与 1970-1-1 0:00:00 UTC 时间相差的秒数

以我在北京时间 2000/1/1 8:00:00 站在东八区为例:

在 JS 中:

// 获取当前本地时间:
new Date()
// 返回:Jan 1 2000 8:00:00 GMT+0800(中国标准时间)

// 获取当前 UTC 时间字符串:
(Local Time).toUTCString()
// 返回:Jan 1 2000 0:00:00 GMT

// 初始化一个 UTC 时间 2000-1-1 0:00:00
new Date(Date.UTC(2000, 1 - 1, 1, 0, 0, 0))

// 获取 UTC 时间的本地时间字符串:
(UTC Time).toLocaleString()


// 本地时间 1970/1/1 8:00:00 的时间戳
new Date(1970, 1 - 1, 1, 8, 0, 0).getTime() / 1000
// 返回:0

// 本地时间 2000/1/1 8:00:00 的时间戳
new Date(2000, 1 - 1, 1, 8, 0, 0).getTime() / 1000
// 返回:946684800

// 本地时间 当前 的时间戳
new Date().getTime() / 1000

// UTC 时间 2000/1/1 0:00:00 的时间戳
new Date(Date.UTC(2000, 1 - 1, 1, 0, 0, 0)).getTime() / 1000
// 或
Date.UTC(2000, 1 - 1, 1, 0, 0, 0) / 1000
// 返回:946684800

在 C# 中:

DateTime 默认的 Kind 是 Local,使用 DateTime.SpecifyKind() 方法可以定义一个 UTC 时间
DateTime.Now 返回当前本地时间
DateTime.UtcNow 返回当前 UTC 时间

// 定义一个本地时间 2000/1/1 8:00:00
new DateTime(2000, 1, 1, 8, 0, 0)

// 定义一个 UTC 时间 2000/1/1 0:00:00
DateTime.SpecifyKind(new DateTime(2000, 1, 1), DateTimeKind.Utc)

// 将 UTC 时间转化为本地时间
(UTC Time).ToLocalTime()

// 将本地时间转化为 UTC 时间
(Local Time).ToUniversalTime()

再次说明,本地时间和 UTC 时间都是 DateTime 对象,关键看定义的时候是 Local 还是 Utc

// 本地时间 1970/1/1 8:00:00 的时间戳
(new DateTime(1970, 1, 1, 8, 0, 0) - DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc).ToLocalTime()).TotalSeconds
// 返回:0

// 本地时间 2000/1/1 8:00:00 的时间戳
(new DateTime(2000, 1, 1, 8, 0, 0) - DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc).ToLocalTime()).TotalSeconds
// 返回:946684800

// 本地时间 当前 的时间戳
(DateTime.Now - DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc).ToLocalTime()).TotalSeconds


// 将时间戳 946684800 转换为本地时间
DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc).ToLocalTime().AddSeconds(946684800)

实战:

如果我们要将时间戳精确到毫秒,那么 JS 直接 .getTime() 即可,不需要 / 1000,C# 将它转换为本地时间时用 AddMilliseconds 代替 AddSeconds。

中国跨越了多个时区却统一使用北京时间,所以国内网站只要记录本地时间即可;如果做国际站或者有不同国家的访客,除非全部由服务器端获取时间,否则客户端 JS 的本地时间(非时间戳)都需要转换成 UTC 时间来跟服务端的时间进行运算和保存,推荐使用时间戳在客户端和服务端之间传递,因为时间戳与时区无关,它是两个相同性质的时间(同为本地时间或同为 UTC 时间)的差值。

xoyozo 9 年前
14,351

兼容建议:(2017年初)

连淘宝都放弃 IE6 了,就不需要再坚持了;

IE7 跟错了老大(Vista),已经没有市场了;

当前市场份额最大的操作系统还是 Win7,所以 IE8 是必须要兼容的,就算国人都安装了国产浏览器,内核也未必会升到 IE9-11。

当然每个站的访客群体不同,具体还得参考网站统计数据来确定兼容级别。

为了友好,建议你在不打算兼容的浏览器上提供升级提示和新版下载链接。

如果是纯移动端,那么大胆地用 HTML5 就行了。

以下例举我遇到过的兼容问题:

浏览器版本 注意事项
IE6-7 <input type="radio" /> 必须设置 name 才能被选中
IE6-7 不支持 console.log
IE6-7 不支持 JSON.stringify
所有 IE 不支持 <input /> 新的 type 类型,查看详情
xoyozo 9 年前
4,964

最近要做个简单的类似 CNZZ 和百度统计的统计器,不可避免地遇到 JS 文件异步加载 和 给 JS 文件传参 的问题。

参考了 CNZZ 的代码以后,在 Chrome 的控制台发现以下警告:

A Parser-blocking, cross-origin script, http://s4.cnzz.com/stat.php?***, is invoked via document.write. This may be blocked by the browser if the device has poor network connectivity. See https://www.chromestatus.com/feature/5718547946799104 for more details.

Paul Kinlan 给出了解释,是因为使用了 document.write() 的方式输出了 <script src="***" /> HTML DOM,建议改成 document.appendChild() 或 parentNode.insertBefore(),最好的例子就是 Google Analytics

<!-- Google Analytics -->
<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->

上述 JavaScript 跟踪代码段可以确保该脚本在所有浏览器中加载和异步执行。

加了一些注释,便于理解,官方英文版

(function (i, s, o, g, r, a, m) {
  i['GoogleAnalyticsObject'] = r;
  // console.log(window['GoogleAnalyticsObject']) // 'ga'
  // console.log(i[r]) // undefined
  i[r] = i[r] || function () { // i[r] 就是 window['ga'],定义了一个函数
    (i[r].q = i[r].q || []).push(arguments) // 往 ga.q 这个数组中增加一项
  },
  i[r].l = 1 * new Date(); // 时间戳,写法等同于 new Date().getTime()
  // console.log(i[r]) // window['ga'] 就是上面那个 function
  a = s.createElement(o), // 创建一个 script 元素
  m = s.getElementsByTagName(o)[0]; // 文档中的第一个脚本(文档中肯定至少已有一个脚本了)
  a.async = 1; // 异步加载
  a.defer = 1; // 兼容旧浏览器(我自己加的)
  a.src = g;
  m.parentNode.insertBefore(a, m) // 将 a 脚本插入到 m 脚本之前
})(window, document, 'script', 'http://***/***.js', 'ga');
// i s o g r
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');

过程是:

创建了一个 <script> 元素,并异步加载 http://***/***.js;初始化了一个全局函数 ga;在 ga() 命令队列中添加了两条命令。

现在我们可以在这个外部 js 中使用 ga.q 这个对象中的数据了,示例:

;(function () {
  console.log(ga.q);
})(window);

简单补充下,async 是 HTML5 属性,使支持异步加载 JS 文件;defer 只支持 IE,作用类似。

测试异步只需要将 js 文件换成服务端页面,并人为设置 sleep 时间即可,阻塞式调用的话会在加载 js 时暂停后续页面的渲染。

xoyozo 9 年前
7,788

收录了一些个人觉得不错的网页开发插件。

由于插件更新频繁,本页如有错误请指正,也欢迎告知更多功能强大、使用方便的插件。

插件简介备注
框架
jQuery最流行的 JS 框架

下载中文文档英文整合文档中文整合文档浏览器支持来自 css88 的文档

官方建议 IE 6-8 使用 1.12.4

Angular中文版
AngularJS (version 1.x)
一套框架,多种平台同时适用手机与桌面MVC 架构,使得开发现代的单一页面应用程序(SPAs:Single Page Applications)变得更加容易
Vue.js是一套用于构建用户界面的渐进式框架。
Bootstrap中文版简洁、直观、强悍的前端开发框架英文文档v3中文文档v2中文文档视频教程主题和模板
jQuery UI为 jQuery 提供更丰富的功能示例:DatepickerColor AnimationShake Effect
功能
jQuery File UploadjQuery 文件上传英文文档
jQuery Cookie读取、写入和删除 cookie浏览器支持文档
json2.jsjson 操作库已弃用,旧 IE 用 jQuery 的 parseJSON,HTML 5 用 JSON.parse
Lightbox

老牌图片浏览插件

推荐使用更强大的 Viewer.js

 
Swiper中文版最现代的移动触摸滑块(Most Modern Mobile Touch Slider)英文文档中文文档,旧浏览器支持版本:2.x.xSwiper 2 英文文档中文文档
jquery-cropper图片裁剪
FastClick用于消除手机浏览器上触摸事件触发之间的 300 毫秒延迟用法不应用的场景
PACE页面加载进度条文档,IE8+
toastrjQuery 通知文档
Autosize一款小巧的,可自动调整 textarea 高度的独立脚本IE9+
X-editable允许您在页面上创建可编辑元素文档Demo
select2一款提供搜索过滤、自定义样式的下拉框插件
jQuery Tags Input标签输入框
用法
Viewer.js图片浏览插件

GitHub(viewerjs)GitHub(jquery-viewer)

jquery-viewer 是 viewerjs 的 jQuery 插件,即在 jQuery 环境中要同时引用这两个脚本。

PDF.jsA general-purpose, web standards-based platform for parsing and rendering PDFs.
编辑器
UEditor百度在线编辑器GitHub 下载文档ASP.NET 部署教程
日期时间
bootstrap-datepickerBootstrap 日期选择器Online Demo
DateTimePicker日期时间选择 
MultiDatesPicker多日期选择 
FullCalendar日历日程事件工作表IE 9+, jQuery 2.0.0+
TimeTo计时、倒计时 
图表
D3.jsD3.js 是基于数据驱动文档工作方式的一款 JavaScript 函数库,主要用于网页作图、生成互动图形,是最流行的可视化库之一。
Highcharts中文版兼容 IE6+、完美支持移动端、图表类型丰富、方便快捷的 HTML5 交互性图表库文档
ECharts百度图表控件 
AntV来自蚂蚁金服的专业、简单、无限可能的可视化解决方案
G2 - 专业易用的可视化类库
G2-mobile - 移动端高性能可视化类库
G6 - 关系图可视化类库
流程图, 关系图, 可视化规范, 地图, 河流图, 力导图, 网络图, UML图, 业务流程图, 时序图
SyntaxHighlighter功能齐全的代码语法高亮插件(JS) 
动态排名数据可视化

将历史数据排名转化为动态柱状图图表

开源代码,非插件,修改使用

GitHub视频教程EV录屏网页示例视频效果
图标
Font Awesome完美的图标字体IE 8+v3.2.1 支持 IE 7进阶用法(定宽/边框/动画/旋转/叠加)
Glyphicons图标字体作为 Bootstrap 组件
Iconfont阿里巴巴矢量图标库用户可以自定义下载多种格式的 icon,也可将图标转换为字体,便于前端工程师自由调整与调用
UI 框架
WeUI同微信原生视觉体验一致的基础样式库DemoWiki
Apple UI Design Resources苹果用户界面设计资源 
xoyozo 9 年前
11,862

当用户向 <input> 或 <textarea> 输入时执行事件。

可用于统计输入字数,判断输入内容是否规范等。

对比事件对比事件特点oninput 事件特点
onkeypress获得当前字符输入前的内容,不能在右键操作时执行获得当前字符输入后的内容
onkeyup不能在右键操作时执行在任何情况的内容变化时执行
onchange在失去焦点时执行,而且值有所改变,推荐用在 <select> 上在输入时执行

但是通过 JS 来更改内容时不触发上述任何事件,不完美的解决方案是使用定时器。

IE8 及更早版本不支持 oninput,可以用 onpropertychange 代替。

BUG:在 IE9 的右键菜单剪切或删除中无效。

jQuery 例子:

$('#mytextarea').on('input propertychange', function () {
  console.log($(this).val().length);
});
xoyozo 9 年前
6,290

// 定义

public enum status { ready, ordered, printed }
public enum statusB { ready = 1, ordered = 3, printed = 5 }

// 将字符串转化为枚举类型

public static status? ConvertStringToEnum_status(string str)
{
  return str != null && Enum.IsDefined(typeof(status), str) ? (status)Enum.Parse(typeof(status), str) : null as status?;
}

// 将数字(索引值)转化为枚举类型

status s = (status)1; // 值为 status.ordered
statusB s = (statusB)1; // 值为 statusB.ready

// 将枚举类型转化为数字(索引值)

int s = (int)status.ordered; // 值为 1
int s = (int)statusB.ready; // 值为 1

// 循环

foreach (status s in Enum.GetValues(typeof(status)))
{
}


当无法序列化或需要序列化为字符串时,在定义枚举前加上:

当使用 System.Text.Json 时为:

[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]

当使用 Newtonsoft.Json 时为:

[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]


xoyozo 9 年前
5,729

在开发微信中的网页时,会遇到一些域名相关的配置:

① 公众号设置 - 功能设置 - 业务域名
② 公众号设置 - 功能设置 - JS接口安全域名
③ 接口权限 - 网页授权获取用户基本信息
④ 商户平台 - 产品中心 - 开发配置 - JSAPI支付授权目录
⑤ 小程序 - 开发 - 开发设置 - 业务域名
⑥ 公众号开发 - 基本设置 - IP白名单

 

第①种 业务域名:相对不重要,只是用来禁止显示“防欺诈盗号,请勿支付或输入qq密码”提示框,可配置 3 个二级或二级以上域名(个人理解是“非顶级域名”,即填写了 b.a.com 的话,对 c.b.a.com 不起作用,待测)。

我们网站的域名和公众号是没有绑定关系的,那么你在打开一个(可能是朋友分享的)网页时,跟哪个公众号的配置去关联呢,答案是 JS-SDK。

测试结果:由于一个月只有3次修改机会,这次先测二级域名,有效;再测顶级域名,有效;删除所有,仍有效。所以应该是缓存作用。过几天再试,然后下个月先测顶级域名,来确定直接填写顶级域名是否对所有二级域名有效。

 

第②种 JS接口安全域名:是配置所配置的域名下的网页可调用 JS-SDK。可配置 5 个一级或一级以上域名(个人理解是“任何级域名”,即填写了 b.a.com 对 c.b.a.com 也有效,但对 c.z.a.com 无效,待测。如果我们拥有顶级域名对应网站的控制权(上传验证文件到网站根目录),直接填写顶级域名即可)。
使用 JS-SDK 的每个网页都必须注入配置信息(wx.config),而之前必须获取 jsapi_ticket,jsapi_ticket api 的调用次数非常有限,必须全局缓存。而获取 jsapi_ticket 之前必须先获取 access_token,同样需要全局缓存。所以,我们专门做个接口,功能是传入需要使用 JS-SDK 的网页的 url,输出 wx.config 需要用到的配置信息,来实现在不同网页(网站)使用 JS-SDK。

 

第③种 网页授权域名:这是已认证的服务号才能享有的特权,主要作用是获取用户在该服务号中的 openidunionid。可配置 1 个 2 个回调域名(可填写任意级别的域名,但仅对该域名的网页(网站)有效,若填写了 a.comb.a.com 是无效的)。

因此,如果我们需要在不同二级域名甚至不同顶级域名下的网页(以下称之为活动页面)实现用户授权,需要做一个统一的代理授权页面(回调域名当然是填写这个页面所在的域名),引导用户依次打开:微信授权页面 - 代理授权页面 - 活动页面,根据开发说明文档,具体实现如下:

当用户第一次打开活动页面时,引导打开微信授权页面(https://open.weixin.qq.com/connect/oauth2/authorize),其中参数 redirect_uri 指定回调地址,即代理授权页面地址,参数 state 指定活动页面地址。微信授权页面返回 code 和 state,code 作为换取网页授权 access_token 的票据。到这一步,本来可以由代理授权页面直接拿这个 code 去换取 access_token、openid 和 unionid 了,但是由于当前用户还在 302 重定向过程中,将这些信息带入到活动页面时势必导致信息泄露,所以这里将 code 追加到 state 指定的网址上后重定向到活动页面,活动页面拿到 code 再通过服务器端向代理授权页面所在服务器请求 openid 和 unionid,并将它们保存于 Session 中视为用户登录。这样,服务号的 appid 和 secret 也能得到保护。代理授权页面请求的微信服务器接口地址是 https://api.weixin.qq.com/sns/oauth2/access_token

注:网页授权 access_token 不同于 JS-SDK 中使用的全局唯一接口调用凭据 access_token,没有请求次数限制。 

流程既然通了,实现逻辑可以这样设定:

活动页面首先判断 Session 中是否有 openid 或 unionid,若有表示已授权登录;没有再判断地址栏是否有 code 参数,若有则调用代理授权页面所在服务器的接口,用 code 换 openid 和 unionid;没有则直接重定向到代理授权页面,带上 state。用 code 换 openid 和 unionid 时若成功则保存至 Session,若失败则仍然重定向到代理授权页面,带上 state,特别注意 state 中的活动页面地址确保没有 code 参数。


第④种 JSAPI支付授权目录:涉及到微信支付时用到,顾名思义是固定某一个网站内的某个目录,以“/”结尾。最多可添加 5 个。如果支付页面在目录 https://www.a.com/b/ 下,那么可以填写 https://www.a.com/b/ 或 https://www.a.com/(建议后者),暂未测试填写 https://a.com/ 会不会起作用。涉及支付安全,建议设置支付页面的最深一层不可写的目录,以防目录内被上传后门文件带来的安全隐患。


第⑤种 小程序业务域名:任何需要在小程序的 web-view 组件中打开的网页,都必须配置小程序业务域名,限制 20 个。该域名要求必须 https,可填入“任何级域名”(建议填顶级域名,即填写了 a.com 对 b.a.com 也有效。如果我们拥有顶级域名对应网站的控制权(上传验证文件到网站根目录),直接填写顶级域名即可)。


第⑥种 IP白名单:仅填写管理全局 access_token 的中控服务器的 IP。

 

总结:在上述自定义接口部署完成后,如果微信中的网页想获取用户的 unionid,则不需要配置域名,直接使用统一的代理授权即可;如果需要使用 JS-SDK 功能,如分享、上传等等,则需要配置 JS 接口安全域名;如果有表单,最好配置一下业务域名。


本文系个人经验总结,部分结果未经证实,欢迎指正!QQ:940534113

xoyozo 9 年前
9,158