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

news2024/11/30 0:41:57

目录

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

能力调整的内容和理由

原有运行方案

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发起的网页授权,是用来获取用户的基本信息的。需要用户手动同意,无须关注,就可在授权后获取该用户的基本信息。

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

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SpringBoot+Vue的防汛应急物资管理系统

本防汛物资管理系统的主要分为管理员角色和用户角色&#xff0c;主要设计的功能包括注册登录管理、密码信息管理、用户信息管理、物资信息管理等模块。 注册登录管理&#xff1a;使用本系统需要打开浏览器&#xff0c;输入相应的网址&#xff0c;如果用户是首次使用本系统&…

下载、安装Jenkins

进入官网 下载Jenkins https://www.jenkins.io 直接点击Download 一般是下长期支持版 因为它是java写的&#xff0c;你要运行它&#xff08;Jenkins.war&#xff09;肯定要有java环境 有两种方式去运行它&#xff0c;一种是下载Tomcat&#xff08;是很经典的java容器或者jav…

Xcode 15 及以上版本:libarclite 库缺少问题

参考链接&#xff1a;Xcode 15 libarclite 缺失问题_sdk does not contain libarclite at the path /ap-CSDN博客 报错: SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarcl…

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

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

QT研究笔记(一)windows 开发环境安装部署

一、Qt 是什么&#xff1f; Qt 是一个跨平台的应用程序开发框架&#xff0c;最初由挪威的 Trolltech 公司开发&#xff0c;并于2008年被诺基亚收购。后来&#xff0c;Qt 框架由 Digia 公司接手&#xff0c;并在2012年成立了 The Qt Company。Qt 提供了一套丰富的工具和类库&am…

为什么越来越多的企业在考虑将ERP从云端迁移到本地?

越来越多的企业在考虑将核心ERP迁移到本地部署&#xff0c;原来实施的时候局限于业务规模、实施成本的原因采用云端部署的方式越来越不再适应于企业规模的发展、系统应用和数据安全的要求。 因此他们都宁愿将云端ERP的数据迁移到本地&#xff0c;使得系统数据和安全更加可控。…

接口测试框架对比

公司计划系统的开展接口自动化测试&#xff0c;需要我这边调研一下主流的接口测试框架给后端测试&#xff08;主要测试接口&#xff09;的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求&#xff0c;看哪个框架更适合我们。 需求 1、接口编写…

python中[[]] * (n)和[[] for _ in range(n)]的区别

1、现象 刷leetcode207的时候碰到一个坑&#xff0c;用[[]] * (n)初始化二维数组&#xff0c;逻辑是正确的&#xff0c;但是结果始终不对。 2、原因 最后定位是初始化语句使用错误导致的&#xff0c;我使用的是[[]] * (n)&#xff0c;应该使用[[] for _ in range(n)] 3、解…

MagicVideo-V2:多阶段高保真视频生成框架

本项工作介绍了MagicVideo-V2&#xff0c;将文本到图像模型、视频运动生成器、参考图像embedding模块和帧内插模块集成到端到端的视频生成流程中。由于这些架构设计的好处&#xff0c;MagicVideo-V2能够生成具有极高保真度和流畅度的美观高分辨率视频。通过大规模用户评估&…

Android学习之路(28) 进程保活组件的封装

前言 远古时代&#xff0c;出现过很多黑科技&#xff0c;比如MarsDaemon&#xff0c;使用双进程守护的方式进行保活&#xff0c;在当时可谓风光无限&#xff0c;可惜在8.0时代到来就被废弃了。 又比如后面出现的1像素Activity的保活方式&#xff0c;说他流氓一点不过分&#…

Linux 驱动开发基础知识——内核对设备树的处理与使用(十)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

344. Reverse String(反转字符串)

题目描述 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 问题分析 以中间字符为轴&#xff0c;将两边的字符对换…

【Vue】组件间通信的7种方法(全)

目录 组件之前的通信方法 1. props/$emit 2.parent/children 3.ref 4.v-model 5.sync 6.attrs,attrs,attrs,listeners 7.provide/inject 7.eventBus 组件之前的通信方法 1. props/$emit 父传子 props 这个只能够接收父组件传来的数据 不能进行修改 可以静态传递 也可…

day35 柠檬水找零 根据身高重建队列 用最少数量的箭引爆气球

题目1&#xff1a;860 柠檬水找零 题目链接&#xff1a;860 柠檬水找零 题意 一杯柠檬水5美元&#xff0c;每位顾客只买一杯柠檬水&#xff0c;支付5美玉&#xff0c;10美元&#xff0c;20美元&#xff0c;必须正确找零 开始时并没有零钱 若可以正确找零&#xff0c;则返回…

操作系统透视:从历史沿革到现代应用,剖析Linux与网站服务架构

目录 操作系统 windows macos Linux 服务器搭建网站 关于解释器的流程 curl -I命令 名词解释 dos bash/terminal&#xff0c;(终端) nginx/apache&#xff08;Linux平台下的&#xff09; iis&#xff08;Windows平台下的&#xff09; GUI(图形化管理接口&#xff…

python coding with ChatGPT 打卡第16天| 二叉树:完全二叉树、平衡二叉树、二叉树的所有路径、左叶子之和

相关推荐 python coding with ChatGPT 打卡第12天| 二叉树&#xff1a;理论基础 python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历 python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历 python coding with ChatGPT 打卡第15天| 二叉树&#xff1a;翻转…

机器翻译后的美赛论文怎么润色

美赛论文的语言表达一直是组委会看重的点&#xff0c;清晰的思路和地道的语言在评审中是重要的加分项。 今天我们就来讲讲美赛论文的语言问题。 我相信有相当一部分队伍在打美赛的时候&#xff0c;出于效率的考量&#xff0c;都会选择先写中文论文&#xff0c;再机翻成英文。 …

海外盲盒系统搭建,加快盲盒企业出海进程

盲盒作为我国的潮流消费模式&#xff0c;融入了潮流、艺术、动漫等多种元素&#xff0c;吸引了使得越来越多的“Z世代”玩家进入到盲盒市场&#xff0c;促进了市场的迅速扩大&#xff0c;同时也吸引了众多企业入场&#xff0c;“盲盒经济”迅速走红。 盲盒走向海外市场 随着盲…

安装配置Oracle 11g 、PLSQL及使用Navicat远程连接Oracle

目录 一、下载 二、安装 1.执行安装程序 2.配置安全更新 3.安装选项 4.系统类 5.网络安装选项 6.选择安装类型 7.选择产品语言 8.选择数据库版本 9.指定安装位置 10.选择配置类型 ​编辑11.指定数据库标识符 12.指定配置选项 13.电子邮箱 14.指定数据库存储…

寒假思维训练day17 C. Equal Frequencies

不知不觉已经过了差不多一个月了&#xff0c;坚持一件事情还是有点收获的&#xff0c;今天更新一道1600的构造。 寒假训练计划day17 摘要&#xff1a; Part1 题意 Part2 题解 (有数学推导&#xff0c;latex形式) Part3 代码 (C版本&#xff0c;有详细注释) Part4 我对构造题…