微信网页授权之使用完整服务解决方案

目录

微信网页授权能力调整造成的问题

能力调整的内容和理由

原有运行方案

is_snapshotuser字段 

改造原有方案

如何复现测试场景

小结


微信网页授权能力调整造成的问题

依附于第三方的开发,做为开发者经常会遇到第三方进行规范和开发的调整,如开发腾讯微信的相关应用。我所经历的如小程序隐私政策调整、信息备案调整、微信授权获取个人信息限制调整等。

最近我们的一些项目因为微信页面授权能力的调整出现了一些问题,对于新用户未经授权前,微信开发团队给出的输出是快照页,该页内所获取的openId等均为虚拟账号数据,并在屏幕下方非常不明显的显示“使用完整服务”,如下图所示:

此图即是微信给出的授权提示,也是我们折中的解决方案,图中所示的提示框源自己于我们通过携带的参数反馈给用户的提示,以引导用户点击下方的“使用完整服务”链接,并进行授权。

能力调整的内容和理由

微信团队给出的解释是当开发者在网页中在不规范使用发起 snsapi_userinfo 网页授权时,微信将默认打开网页快照页模式进行基础浏览。

微信网页授权规范

  1. 授权流程需引导清晰、准确:在申请获取用户信息的弹窗出现前,应该清晰、准确地告知用户获取信息的范围及获取信息的目的;
  2. 必要场景申请:在必须获取用户信息时才申请,而不是用户尚未了解服务前就强制弹窗。如使用医院挂号时才需要获取用户信息;
  3. 不强制登录:提供游客模式,供用户了解网页提供的基础服务,不强制用户允许网页获取用户信息后才能使用网页服务。

常见的微信网页授权不规范使用案例

  1. 强制登录:在用户打开网页时立即要求用户授权,用户拒绝后无法使用网页提供的服务;
  2. 违规收集个人信息:未在网页提前告知使用个人信息的目的、方式和范围;
  3. 非必要收集:非必要获取用户信息的网页,如文章、视频等,要求用户在浏览内容前登录;
  4. 差别对待微信用户:同样的网页在浏览器内可以无需登录直接访问,在微信内却要求用户先登录才可访问。

原有运行方案

微信OA2授权访问地址如下(示例url为C#字符串):

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7964497eb8bad783&redirect_uri=https%3A//www.leadihr.com/weixin/oa2.aspx%3F&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect&connect_redirect = 1

重定向接收地址 OA2.ASPX程序 (C#版本)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Collections;
using System.Net;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using LitJson;
using System.Data;
using System.Data.SqlClient;
using CosysJaneCommonAPI;
using System.Web.Script.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

public partial class oa2 : System.Web.UI.Page
{


    string Appid = "";
    string appsecret = "";

    string domain = "";


    
    public class OAuth_Token
    {
        public OAuth_Token()
        {
        }
        //access_token  网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同  
        //expires_in    access_token接口调用凭证超时时间,单位(秒)  
        //refresh_token 用户刷新access_token  
        //openid    用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID  
        //scope 用户授权的作用域,使用逗号(,)分隔  
        public string access_token { get; set; }
        public string expires_in { get; set; }
        public string refresh_token { get; set; }
        public string openid { get; set; }
        public string scope { get; set; }

    }


    public class OAuthUser
    {
        public OAuthUser()
        { }
        #region 数据库字段
        private string _openID;
        private string _searchText;
        private string _unionid;
        private string _nickname;
        private string _sex;
        private string _province;
        private string _city;
        private string _country;
        private string _headimgUrl;
//        private string _privilege;
        #endregion

        #region 字段属性
        /// <summary>  
        /// 用户的唯一标识  
        /// </summary>  
        public string openid
        {
            set { _openID = value; }
            get { return _openID; }
        }
        public string SearchText
        {
            set { _searchText = value; }
            get { return _searchText; }
        }
        /// <summary>  
        /// 用户昵称   
        /// </summary>  
        public string nickname
        {
            set { _nickname = value; }
            get { return _nickname; }
        }
        public string unionid
        {
            set { _unionid = value; }
            get { return _unionid; }
        }
        /// <summary>  
        /// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知   
        /// </summary>  
        public string sex
        {
            set { _sex = value; }
            get { return _sex; }
        }
        /// <summary>  
        /// 用户个人资料填写的省份  
        /// </summary>  
        public string province
        {
            set { _province = value; }
            get { return _province; }
        }
        /// <summary>  
        /// 普通用户个人资料填写的城市   
        /// </summary>  
        public string city
        {
            set { _city = value; }
            get { return _city; }
        }
        /// <summary>  
        /// 国家,如中国为CN   
        /// </summary>  
        public string country
        {
            set { _country = value; }
            get { return _country; }
        }
        /// <summary>  
        /// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空  
        /// </summary>  
        public string headimgurl
        {
            set { _headimgUrl = value; }
            get { return _headimgUrl; }
        }
        /// <summary>  
        /// 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)其实这个格式称不上JSON,只是个单纯数组  
        /// </summary>  
        //public string privilege
        //{
        //    set { _privilege = value; }
        //    get { return _privilege; }
        //}
        #endregion
    }      

protected void Page_Load(object sender, EventArgs e)  
    {

        if (!IsPostBack)  
        {
            if (!string.IsNullOrEmpty(Request.QueryString["code"]))  
            {  
                string Code = Request.QueryString["code"].ToString();
                string State = Request.QueryString["state"].ToString();
                //获得Token  
                OAuth_Token Model = Get_token(Code);
                OAuthUser OAuthUser_Model = Get_UserInfo(Model.access_token, Model.openid);
                string content=Model.access_token+ "用户OPENID:" + OAuthUser_Model.openid + "<br>用户昵称:" + OAuthUser_Model.nickname + "<br>性别:" + OAuthUser_Model.sex + "<br>所在省:" + OAuthUser_Model.province + "<br>所在市:" + OAuthUser_Model.city + "<br>所在国家:" + OAuthUser_Model.country + "<br>头像地址:" + OAuthUser_Model.headimgurl + "<br>用户特权信息:";




                    Response.Redirect("https://x.x.com/index.aspx?&oid=" + OAuthUser_Model.openid);
                  
            }  
        }  
    }
public class JsonHelper
{
    /// <summary>
    /// 生成Json格式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string GetJson<T>(T obj)
    {
        DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
        using (MemoryStream stream = new MemoryStream())
        {
            json.WriteObject(stream, obj);
            string szJson = Encoding.UTF8.GetString(stream.ToArray()); return szJson;
        }
    }
    /// <summary>
    /// 获取Json的Model
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="szJson"></param>
    /// <returns></returns>
    public static T ParseFromJson<T>(string szJson)
    {
        T obj = Activator.CreateInstance<T>();
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
            return (T)serializer.ReadObject(ms);
        }
    }
}  
    //获得Token  
    protected OAuth_Token Get_token(string Code)  
    {  
        string Str = GetJson("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + Appid + "&secret=" + appsecret + "&code=" + Code + "&grant_type=authorization_code");
        
        
        OAuth_Token Oauth_Token_Model = JsonHelper.ParseFromJson<OAuth_Token>(Str);  
        return Oauth_Token_Model;  
    }  
    //刷新Token  
    protected OAuth_Token refresh_token(string REFRESH_TOKEN)  
    {  
        string Str = GetJson("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + Appid + "&grant_type=refresh_token&refresh_token=" + REFRESH_TOKEN);  
        OAuth_Token Oauth_Token_Model = JsonHelper.ParseFromJson<OAuth_Token>(Str);  
        return Oauth_Token_Model;  
    }  
    //获得用户信息  
    protected OAuthUser Get_UserInfo(string REFRESH_TOKEN, string OPENID)  
    {  
       // Response.Write("获得用户信息REFRESH_TOKEN:" + REFRESH_TOKEN + "||OPENID:" + OPENID);  
        string Str = GetJson("https://api.weixin.qq.com/sns/userinfo?access_token=" + REFRESH_TOKEN + "&openid=" + OPENID + "&lang=zh_CN");  
        OAuthUser OAuthUser_Model = JsonHelper.ParseFromJson<OAuthUser>(Str);
        return OAuthUser_Model;  
    }  
    protected string GetJson(string url)  
    {  
        WebClient wc = new WebClient();  
        wc.Credentials = CredentialCache.DefaultCredentials;  
        wc.Encoding = Encoding.UTF8;
        string returnText = "";
        try
        {
            returnText = wc.DownloadString(url);
        }
        catch (Exception e)
        {
            Response.Write(e.Message);
            Response.End();
        }
        if (returnText.Contains("errcode"))  
        {  
            //可能发生错误  
        }  
        //Response.Write(returnText);  
        return returnText;  
    }  
  
}

is_snapshotuser字段 

通过code换取网页授权access_token
请求方法是获取code后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

正确时会返回具有如下图所示的JSON数据包:

因此可能通过判断 is_snapshotuser 字段是否为1,判断是否快照页模式

改造原有方案

主要是增加 string is_snapshotuser = "0" 和后续对JSON返回值的判断,并返回回调的url并携带此参数。示例代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Collections;
using System.Net;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using LitJson;
using System.Data;
using System.Data.SqlClient;
using CosysJaneCommonAPI;
using System.Web.Script.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

public partial class oa2 : System.Web.UI.Page
{


    string Appid = "";
    string appsecret = "";

    string domain = "";
    string is_snapshotuser = "0";


    
    public class OAuth_Token
    {
        public OAuth_Token()
        {
        }
        //access_token  网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同  
        //expires_in    access_token接口调用凭证超时时间,单位(秒)  
        //refresh_token 用户刷新access_token  
        //openid    用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID  
        //scope 用户授权的作用域,使用逗号(,)分隔  
        public string access_token { get; set; }
        public string expires_in { get; set; }
        public string refresh_token { get; set; }
        public string openid { get; set; }
        public string scope { get; set; }

    }


    public class OAuthUser
    {
        public OAuthUser()
        { }
        #region 数据库字段
        private string _openID;
        private string _searchText;
        private string _unionid;
        private string _nickname;
        private string _sex;
        private string _province;
        private string _city;
        private string _country;
        private string _headimgUrl;
//        private string _privilege;
        #endregion

        #region 字段属性
        /// <summary>  
        /// 用户的唯一标识  
        /// </summary>  
        public string openid
        {
            set { _openID = value; }
            get { return _openID; }
        }
        public string SearchText
        {
            set { _searchText = value; }
            get { return _searchText; }
        }
        /// <summary>  
        /// 用户昵称   
        /// </summary>  
        public string nickname
        {
            set { _nickname = value; }
            get { return _nickname; }
        }
        public string unionid
        {
            set { _unionid = value; }
            get { return _unionid; }
        }
        /// <summary>  
        /// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知   
        /// </summary>  
        public string sex
        {
            set { _sex = value; }
            get { return _sex; }
        }
        /// <summary>  
        /// 用户个人资料填写的省份  
        /// </summary>  
        public string province
        {
            set { _province = value; }
            get { return _province; }
        }
        /// <summary>  
        /// 普通用户个人资料填写的城市   
        /// </summary>  
        public string city
        {
            set { _city = value; }
            get { return _city; }
        }
        /// <summary>  
        /// 国家,如中国为CN   
        /// </summary>  
        public string country
        {
            set { _country = value; }
            get { return _country; }
        }
        /// <summary>  
        /// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空  
        /// </summary>  
        public string headimgurl
        {
            set { _headimgUrl = value; }
            get { return _headimgUrl; }
        }
        /// <summary>  
        /// 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)其实这个格式称不上JSON,只是个单纯数组  
        /// </summary>  
        //public string privilege
        //{
        //    set { _privilege = value; }
        //    get { return _privilege; }
        //}
        #endregion
    }      

protected void Page_Load(object sender, EventArgs e)  
    {

        if (!IsPostBack)  
        {
            if (!string.IsNullOrEmpty(Request.QueryString["code"]))  
            {  
                string Code = Request.QueryString["code"].ToString();
                string State = Request.QueryString["state"].ToString();
                //获得Token  
                OAuth_Token Model = Get_token(Code);
                OAuthUser OAuthUser_Model = Get_UserInfo(Model.access_token, Model.openid);
                string content=Model.access_token+ "用户OPENID:" + OAuthUser_Model.openid + "<br>用户昵称:" + OAuthUser_Model.nickname + "<br>性别:" + OAuthUser_Model.sex + "<br>所在省:" + OAuthUser_Model.province + "<br>所在市:" + OAuthUser_Model.city + "<br>所在国家:" + OAuthUser_Model.country + "<br>头像地址:" + OAuthUser_Model.headimgurl + "<br>用户特权信息:";




                    Response.Redirect("https://x.x.com/index.aspx?&oid=" + OAuthUser_Model.openid+"&is_snapshotuser="+is_snapshotuser);
                  
            }  
        }  
    }
public class JsonHelper
{
    /// <summary>
    /// 生成Json格式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string GetJson<T>(T obj)
    {
        DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
        using (MemoryStream stream = new MemoryStream())
        {
            json.WriteObject(stream, obj);
            string szJson = Encoding.UTF8.GetString(stream.ToArray()); return szJson;
        }
    }
    /// <summary>
    /// 获取Json的Model
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="szJson"></param>
    /// <returns></returns>
    public static T ParseFromJson<T>(string szJson)
    {
        T obj = Activator.CreateInstance<T>();
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
            return (T)serializer.ReadObject(ms);
        }
    }
}  
    //获得Token  
    protected OAuth_Token Get_token(string Code)  
    {  
        string Str = GetJson("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + Appid + "&secret=" + appsecret + "&code=" + Code + "&grant_type=authorization_code");
        if (Str.IndexOf("\"is_snapshotuser\":1") != -1||Str.IndexOf("\"is_snapshotuser\": 1")!=-1)
        {
            is_snapshotuser = "1";
        }
        OAuth_Token Oauth_Token_Model = JsonHelper.ParseFromJson<OAuth_Token>(Str);  
        return Oauth_Token_Model;  
    }  
    //刷新Token  
    protected OAuth_Token refresh_token(string REFRESH_TOKEN)  
    {  
        string Str = GetJson("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + Appid + "&grant_type=refresh_token&refresh_token=" + REFRESH_TOKEN);  
        OAuth_Token Oauth_Token_Model = JsonHelper.ParseFromJson<OAuth_Token>(Str);  
        return Oauth_Token_Model;  
    }  
    //获得用户信息  
    protected OAuthUser Get_UserInfo(string REFRESH_TOKEN, string OPENID)  
    {  
       // Response.Write("获得用户信息REFRESH_TOKEN:" + REFRESH_TOKEN + "||OPENID:" + OPENID);  
        string Str = GetJson("https://api.weixin.qq.com/sns/userinfo?access_token=" + REFRESH_TOKEN + "&openid=" + OPENID + "&lang=zh_CN");  
        OAuthUser OAuthUser_Model = JsonHelper.ParseFromJson<OAuthUser>(Str);
        return OAuthUser_Model;  
    }  
    protected string GetJson(string url)  
    {  
        WebClient wc = new WebClient();  
        wc.Credentials = CredentialCache.DefaultCredentials;  
        wc.Encoding = Encoding.UTF8;
        string returnText = "";
        try
        {
            returnText = wc.DownloadString(url);
        }
        catch (Exception e)
        {
            Response.Write(e.Message);
            Response.End();
        }
        if (returnText.Contains("errcode"))  
        {  
            //可能发生错误  
        }  
        //Response.Write(returnText);  
        return returnText;  
    }  
  
}

这样可以在业务页面,如上述代码中的index.aspx进行如下判断:

if (Request.QueryString["is_snapshotuser"] == "1")
{
    Layer.open("使用前微信要求您的授权,请点击下方使用完整服务后继续...", "'确定'", "info");
    return;
}

如何复现测试场景

已经授权的用户,如果想测试重新授权的场景,请打开微信,依如下步骤进行设置:

 

 

 

 

小结

以上示例是一种较小改动的解决方案,个人比较习惯于应用程序稳定性第一的思路。如果已经使用新规则设计方案则可仅供参考。

另外在此介绍一下关于网页授权的两种scope的区别:
1、以snsapi_base为scope发起的网页授权,可以直接获取进入页面的用户的openid,且是静默授权并自动跳转到业务页面。
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。需要用户手动同意,无须关注,就可在授权后获取该用户的基本信息。

以上是个人的一些观点和解决方案,感谢阅读,并提出指正。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/370604.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PCL安装以及CGAL构建三维凸包

基础理论专栏目录 - 知乎 (zhihu.com) 凸包问题——概述 - 知乎 (zhihu.com) 1、安装PCL 安装pcl,我的是window10,vs2019。我安装的是1.13 win10系统下 VS2019点云库PCL1.12.0的安装与配置_windows 10使用pcl-CSDN博客 照着上述博客进行配置&#xff0c;再结合这个设置环境变…

微信小程序(三十三)promise异步写法

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.promise异步与普通异步的写法区别 2.promise异步的优势 源码&#xff1a; index.wxml <view class"preview" bind:tap"onChoose"><image src"{{avatar}}" mode"…

WorkPlus Meet视频会议系统,支持局域网部署

随着科技的不断发展&#xff0c;视频会议系统已经成为企业、教育机构和医疗领域等各行各业远程协作和沟通的重要工具。恒拓高科的WorkPlus Meet视频会议系统以其强大的功能和便捷的操作&#xff0c;满足了不同行业的实际需求&#xff0c;成为市场上备受青睐的解决方案。 在金融…

Vue3+TS+Vite+Pinia最全学习总结

VUE3介绍 vue2和vue3之间的区别 因为需要遍历data对象上所有属性&#xff0c;所以如果data对象属性结构嵌套很深&#xff0c;就会存在性能问题。因为需要遍历属性&#xff0c;所有需要提前知道对象上有哪些属性&#xff0c;才能将其转化为getter和setter,所以vue2中无法将data新…

【详细教程】Kubernetes集群部署:使用kubeadm创建集群

文章目录 一、虚拟机准备&#xff08;一&#xff09;主机基本配置&#xff08;二&#xff09;安装docker&#xff08;三&#xff09;配置cri-docker环境&#xff08;四&#xff09;安装kubeadm、kubelet、kubectl&#xff08;五&#xff09;克隆主机 二、环境配置工作&#xff…

阿里计算巢:开启数据集市场的宝库,助力AI研究和应用

阿里计算巢 阿里数据巢提供了一个丰富的数据集市场&#xff0c;官方地址&#xff1a; https://computenest.console.aliyun.com/dataset/service/cn-hangzhou 可以看到数据集内容涵盖了多个领域&#xff0c;且还在不断增加中。关键是免费&#xff01;且支持下载到本地。 以下…

MC插件服教程-paper+游戏云VPS

首先必须要先买一台VPS&#xff0c;这里以i9的机型做演示 购买完成等待大约1分钟服务器就会创建完成&#xff0c;之后在管理页可以看到服务器的连接信息 image772356 43 KB 首先复制下远程连接地址&#xff0c;此处即k.rainplay.cn:13192 之后在系统里搜索“rdp”或“远程桌面…

一文学会yum源配置(联网/未联网)以及yum常用命令

1、yum源介绍 yum&#xff08;Yellow dog Updater Modified的简称&#xff09;&#xff0c;yum的宗旨是自动化地升级&#xff0c;安装/移除rpm包&#xff0c;收集rpm包的相关信息&#xff0c;检查依赖性并自动提示用户解决。yum的关键之处是要有可靠的repository&#xff0c;顾…

Linux安装svn服务器和权限配置_亲测成功

Linux安装svn服务器和权限配置_亲测成功 SVN简介 SVN是Subversion的简称&#xff0c;是一个开放源代码的版本控制系统&#xff0c;通过采用分支管理系统的高效管理&#xff0c;简而言之就是用于多个人共同开发同一个项目&#xff0c;实现共享资源&#xff0c;实现最终集中式的…

C# OMRON PLC FINS TCP协议简单测试

FINS(factory interface network service)通信协议是欧姆龙公司开发的用于工业自动化控制网络的指令&#xff0f;响应系统。运用 FINS指令可实现各种网络间的无缝通信&#xff0c;包括用于信息网络的 Etherne(以太网)&#xff0c;用于控制网络的Controller Link和SYSMAC LINK。…

【C++】C++入门 — 类和对象初步介绍

类和对象 1 类的作用域2 类的实例化3 类对象模型4 this指针介绍&#xff1a;特性&#xff1a; Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 1 类的作用域 类定义了一个新的作用域&#xff0c;类的…

stable-diffusion | v1-5-pruned.ckpt和v1-5-pruned-emaonly.ckpt的区别

https://github.com/runwayml/stable-diffusion?tabreadme-ov-file#reference-sampling-script 对于 1.5 模型&#xff0c;其中可能包括四部分&#xff1a;标准模型、文本编码器、VAE模型、EMA模型。 标准模型&#xff1a;生成图片的核心模块&#xff0c;潜空间中的前向扩散和…

创新大赛专访丨南沙人才荣膺2023年度人才寻猎标杆品牌:吸纳海内外高学历人才,助力南沙精准“选苗”

日前&#xff0c;2023第三届全国人力资源创新大赛颁奖典礼暨成果展圆满举行。自2023年10月份启动以来&#xff0c;大赛共吸引了457个案例报名参赛&#xff0c;经组委会专家团队评审严格审核&#xff0c;企业赛道共有103个案例获奖、72家企业、13位个人、7个产业园斩获荣誉。 广…

SpringMVC-组件解析

一、引子 我们在上一篇文章Spring MVC-基本概念中&#xff0c;为读者解释了如何使用SpringMVC框架&#xff0c;将承接客户端请求的工作从原生的Servlet转移到我们熟知的Controller中。那么我们不禁会好奇&#xff0c;SpringMVC框架到底做了什么&#xff0c;是怎么把请求分发给…

【涵子来信】——拆机,感想

大家好&#xff0c;我是涵子。 初中的第一个学期结束了&#xff0c;来临寒假。我在寒假做了一件有趣的事情&#xff1a;拆机&#xff0c;修手机。今天我来分享分享这件事情。 拆机 情况介绍 拆机对象&#xff1a; iPhone 6 Plus 情况&#xff1a; 电池健康度100%&#xff08…

张维迎《博弈与社会》威胁与承诺(4)宪政与民主

有限政府 动态博弈理论对我们理解民主与法治具有重要的意义。 自人类进入文明时代以来&#xff0c;政府就是社会博弈重要的参与人。任何社会要有效运行&#xff0c;都需要赋予政府一些自由裁量权。但如果政府的自由裁量权太大&#xff0c;政府官员为所欲为&#xff0c;不仅老百…

最新酒桌小游戏喝酒骰子小程序源码/带流量主

2023最新酒桌小游戏喝酒小程序源码-带流量主&#xff0c;喝酒神器3.6修改增加了广告位&#xff0c;直接上传源码到开发者端即&#xff0c;可通过后改广告代码&#xff0c;然后关闭广告展示提交&#xff0c;通过后打开即可。 流量主ID替换插屏广告位 adunit-29629a7b54a41a8b视频…

2024年【G2电站锅炉司炉】模拟试题及G2电站锅炉司炉考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【G2电站锅炉司炉】模拟试题及G2电站锅炉司炉考试试题&#xff0c;包含G2电站锅炉司炉模拟试题答案和解析及G2电站锅炉司炉考试试题练习。安全生产模拟考试一点通结合国家G2电站锅炉司炉考试最新大纲及G2电站锅…

MySQL 教程 2.3

MySQL DELETE 语句 你可以使用 DELETE FROM 命令来删除 MySQL 数据表中的记录。 你可以在 mysql> 命令提示符或 PHP 脚本中执行该命令。 语法 以下是 DELETE 语句从 MySQL 数据表中删除数据的通用语法&#xff1a; DELETE FROM table_name WHERE condition; 参数说明&…

JAVA单例模式详解

单例模式 创建型模式提供创建对象的机制,能够提升已有代码的灵活性和复用性 常用的有&#xff1a;单例模式、工厂模式&#xff08;工厂方法和抽象工厂&#xff09;、建造者模式。 不常用的有&#xff1a;原型模式。 1 单例模式介绍 1.1 定义 单例模式&#xff08;Singlet…