基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(六)

news2024/11/25 20:55:49

目录

  • 前言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
  • 模块实现
    • 1. 模型训练
      • 1)数据集分析
      • 2)数据预处理
      • 3)模型创建
      • 4)模型训练
      • 5)获取特征矩阵
    • 2. 后端Django
    • 3. 前端微信小程序
      • 1)小程序全局配置文件
      • 2)推荐电影页面
      • 3)个人信息界面以及用户登录记录页面
  • 相关其它博客
  • 工程源代码下载
  • 其它资料下载


在这里插入图片描述

前言

本项目专注于MovieLens数据集,并采用TensorFlow中的2D文本卷积网络模型。它结合了协同过滤算法来计算电影之间的余弦相似度,并通过用户的交互方式,以单击电影的方式,提供两种不同的电影推荐方式。

首先,项目使用MovieLens数据集,这个数据集包含了大量用户对电影的评分和评论。这些数据用于训练协同过滤算法,以便推荐与用户喜好相似的电影。

其次,项目使用TensorFlow中的2D文本卷积网络模型,这个模型可以处理电影的文本描述信息。模型通过学习电影的文本特征,能够更好地理解电影的内容和风格。

当用户与小程序进行交互时,有两种不同的电影推荐方式:

  1. 协同过滤推荐:基于用户的历史评分和协同过滤算法,系统会推荐与用户喜好相似的电影。这是一种传统的推荐方式,通过分析用户和其他用户的行为来推荐电影。

  2. 文本卷积网络推荐:用户可以通过点击电影或输入文本描述,以启动文本卷积网络模型。模型会分析电影的文本信息,并推荐与输入的电影或描述相匹配的其他电影。这种方式更注重电影的内容和情节相似性。

综合来看,本项目融合了协同过滤和深度学习技术,为用户提供了两种不同但有效的电影推荐方式。这可以提高用户体验,使他们更容易找到符合他们口味的电影。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。
在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

模型训练流程如图所示。

在这里插入图片描述

服务器运行流程如图所示。

在这里插入图片描述

运行环境

本部分包括Python环境、TensorFlow环境、 后端服务器、Django和微信小程序环境。

模块实现

本项目包括3个模块:模型训练、后端Django、 前端微信小程序模块,下面分别给出各模块的功能介绍及相关代码。

1. 模型训练

下载数据集,解压到项目目录下的./ml-1m文件夹下。数据集分用户数据users.dat、电影数据movies.dat和评分数据ratings.dat。

1)数据集分析

数据集网站地址为http://files.grouplens.org/datasets/movielens/ml-1m-README.txt对数据的描述。

相关博客:https://blog.csdn.net/qq_31136513/article/details/133124641#1_44

2)数据预处理

通过研究数据集中的字段类型,发现有一些是类别字段,将其转成独热编码,但是UserID、MovieID的字段会变稀疏,输入数据的维度急剧膨胀,所以在预处理数据时将这些字段转成数字。

相关博客:https://blog.csdn.net/qq_31136513/article/details/133124641#2_123

3)模型创建

相关博客:https://blog.csdn.net/qq_31136513/article/details/133125845#3_50

4)模型训练

相关博客:https://blog.csdn.net/qq_31136513/article/details/133130704#4_57

5)获取特征矩阵

本部分包括定义函数张量、生成电影特征矩阵、生成用户特征矩阵。

相关博客:https://blog.csdn.net/qq_31136513/article/details/133130704#5_240

2. 后端Django

该模块实现了推荐算法的封装与前端数据交互功能。

相关博客:https://blog.csdn.net/qq_31136513/article/details/133131103#2_Django_67

3. 前端微信小程序

该模块实现用户交互以及与后端数据的传输功能,通过微信开发者平台进行前端开发。

1)小程序全局配置文件

全局配置文件通常以APP开头,包括app.jsapp.jsonapp.wxss等, 这些文件在新建小程序时,由微信开发者平台自动生成。

app.js相关代码如下:

//app.js
App({
  onLaunch: function () {
    console.log("app launch")
    //展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)
    //登录
    wx.login({
      success: res => {
      }
    });
    //获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          //已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              //可以将res发送给后台解码出unionId
              this.globalData.userInfo = res.userInfo
              //由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              //此处加入callback 以防止类似情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null,
  }
})

文件app.json为json格式,不能添加注释。pages表示小程序包含的页面,共有三个,一是电影推荐页面movies;二是个人信息页面index;三是用户登录记录logs; window是标题栏设置,可以更改文字类型、背景颜色、标题文字; tabBar是 底部导航栏,可以选择当前页面,包含各页面的路径以及图标,图标可以在阿里巴巴矢量图标库https://www.iconfont.cn/中找到,其他为默认配置。

相关代码如下:

{
  "pages": [
    "pages/movies/movies",
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Movies",
    "navigationBarTextStyle": "black"
  },
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/movies/movies",
        "text": "Movies",
        "iconPath": "/icon/movie.png",
        "selectedIconPath": "/icon/movie_selected.png"
      },
      {
        "pagePath": "pages/index/index",
        "text": "Mine",
        "iconPath": "/icon/user.png",
        "selectedIconPath": "/icon/user_selected.png"
      }
    ]
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

文件app.wxss中描述了小程序的样式表,用于配置全局页面元素样式,app.wxss相关代码如下:

/**app.wxss**/
@import './weui-miniprogram/weui-wxss/dist/style/weui.wxss';
/*定义了container的样式*/
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 200rpx 0;
  box-sizing: border-box;
} 

2)推荐电影页面

推荐电影页面movies,包含movies.jsmovies.jsonmovies.wxmlmovies.wxss。其中movies.js记录的是逻辑层; movies.wxml记录的是视图层; movies.wxss记录页面元素的样式表;movies.json 类似于app.json,记录这个页面的相关配置信息。

相关代码如下:

//pages/movies/movies.js
Page({
  /*页面的初始数据*/
  data: {
    //电影相关信息
    movies: null,
    //推荐方式
    recommend_mode: null,
    //推荐方式选择信息
    recommend_mode_list: [{
      name: "同类型电影", value: 0, checked: "false"
    },
    {
      name: "看过这个的还喜欢看", value: 1, checked: "true"
    }]
  },
  //页面单选按钮逻辑功能函数,选择推荐方式时触发
  radioChange: function (e) {
    //用单选按钮的值给推荐方式变量赋值
    this.setData({ recommend_mode: e.detail.value })
    console.log(this.data.recommend_mode)
  },
  //推荐同类型电影
  post_st_movies: function (event) {
    var that = this;
    //向后端服务器发出请求
    wx.request({
      //这里url填写用户服务器的域名,不显示
      url: '',
      //发送数据为电影的ID
      data: {
        movie_id: event.currentTarget.dataset.movie_id,
      },
      //POST方法
      method: 'post',
      header: {
        'content-type': 'application/x-www-form-urlencoded' //默认值
      },
      //成功后执行
      success(res) {
      //更新电影信息
        that.setData({ movies: res.data })
        console.log(that.data.movies[0].movie_id);
      }
    })
  },
    //推荐看过这个电影的人喜欢的电影
  post_of_movies: function (event) {
    var that = this;
    //向后端服务器发出请求
    wx.request({
      //这里url填写用户服务器的域名,不显示
      url: '',
      //发送数据为电影的ID
      data: {
        movie_id: event.currentTarget.dataset.movie_id,
      },
      //POST方法
      method: 'post',
      header: {
        'content-type': 'application/x-www-form-urlencoded' //默认值
      },
      //成功后执行
      success(res) {
        //更新电影信息
        that.setData({ movies: res.data })
        console.log(that.data.movies[0].movie_id);
      }
    })
  },
  //电影推荐按钮的逻辑功能
  recommend_movies: function (event) {
    //如果是0模式
    if (this.data.recommend_mode == 0) {
      this.post_st_movies(event);
    }
    //如果是1模式
    else if (this.data.recommend_mode == 1) {
      this.post_of_movies(event);
    }
  },
   //随机获取电影函数逻辑功能
  get_rand_movies: function () {
    var that = this;
    //向后端服务器发出请求
    wx.request({
      //url填写用户服务器的域名,不显示
      url: '',
      data: {
      },
      //GET方法
      method: 'get',
      header: {
        'content-type': 'application/x-www-form-urlencoded' //默认值
      },
      //成功后执行
      success(res) {
        //更新电影信息
        that.setData({ movies: res.data })
        console.log(that.data.movies[0].movie_id);
      }
    })
  },
  /*生命周期函数--监听页面加载*/
  onLoad: function (options) {
    this.get_rand_movies();
  },
  /*生命周期函数--监听页面初次渲染完成*/
  onReady: function () {
  },
  /* 生命周期函数--监听页面显示*/
  onShow: function () {
  },
  /*生命周期函数--监听页面隐藏*/
  onHide: function () {
  },
  /*生命周期函数--监听页面卸载*/
  onUnload: function () {
  },
  /*页面相关事件处理函数--监听用户下拉动作*/
  onPullDownRefresh: function () {
  },
  /*页面上拉触底事件的处理函数*/
  onReachBottom: function () {
  },
  /*用户单击右上角分享*/
  onShareAppMessage: function () {
  }
})
//文件movies.json代码为空,movies.wxml相关代码如下:
<!--pages/movies/movies.wxml-->
<!--页面容器-->
<view class="container">
  <!--页面-->
  <view class="page-body">
    <!--推荐方式选择容器-->
    <view class="mode-choose-container">
      <text>请选择推荐方式:</text>
      <radio-group class="mode-choose" bindchange="radioChange">
        <radio class="radio" wx:for-items="{{recommend_mode_list}}" value="{{item.value}}" >
          <text>{{item.name}}</text>
        </radio>
      </radio-group>
    </view>
    <!--电影信息容器-->
    <view class="movie-container" wx:for="{{[0,1,2,3,4]}}" hover-class='hover_list' data-movie_id="{{movies[index].movie_id}}" bindtap="recommend_movies">
      <text>Top {{index+1}}</text>
      <!--电影名称-->
      <view class="movie-name-container">
        <text class="movie-name">
          {{movies[index].movie_name}}
        </text>
      </view>
      <!--电影流派-->
      <view class="movie-genres-container">
        <text class="movie-genres">
          {{movies[index].movie_genres}}
        </text>
      </view>
    </view>
  </view>
</view>
//movies.wxss相关代码
/* pages/movies/movies.wxss */
.container {
  /*透明度: 0.1*/
  align-items: center;
  background: #f5f5f5;
}
.page-body {
  /*透明度:0.2*/
  align-items: center;
  background: #fefefe;
  border-style: solid;
  border-color: #b2b2b2;
  border-width: thin medium medium thin;
  border-radius: 50rpx;
  width: 660rpx;
}
.mode-choose-container {
  align-items: center;
  padding:20rpx;
}
.movie-container {
  align-items: center;
  border-style: solid;
  border-color: #b2b2b2;
  border-width: thin medium medium thin;
  border-radius: 50rpx;
  margin: 20rpx 15rpx 20rpx 15rpx;
  padding:20rpx;
  text-align: center;
}
.hover_list {
  opacity: 0.9;
  background: #f7f7f7;
}

3)个人信息界面以及用户登录记录页面

这两个页面是新建小程序时系统自动生成的,不做改动。以下个人信息页面由index.jsindex.htmlindex.jsonindex.wxss等文件构成。

index.js相关代码如下:

//获取应用实例
const app = getApp()
Page({
  data: {
    motto: 'Hope you find your peace.',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
//由于getUserInfo是网络请求,可能会在Page.onLoad后才返回
//此处加入callback 防止这种情况发生
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      //在没有 open-type=getUserInfo版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  }
})
//index.html相关代码
<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>
//文件index.json为空,index.wxss相关代码
/**index.wxss**/
.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.userinfo-avatar {
  width: 128rpx;
  height: 128rpx;
  margin: 20rpx;
  border-radius: 50%;
}
.userinfo-nickname {
  color: #aaa;
}
.usermotto {
  margin-top: 200px;
}

以下是用户登录记录页面,由logs.jslogs.htmllogs.jsonlogs.wxss等文件构成。

logs.js相关代码如下:

//logs.js
const util = require('../../utils/util.js')
Page({
  data: {
    logs: []
  },
  onLoad: function () {
    this.setData({
      logs: (wx.getStorageSync('logs') || []).map(log => {
        return util.formatTime(new Date(log))
      })
    })
  }
})
//logs.html相关代码
<!--logs.wxml-->
<view class="container log-list">
  <block wx:for="{{logs}}" wx:for-item="log">
    <text class="log-item">{{index + 1}}. {{log}}</text>
  </block>
</view>
//logs.wxss代码如下:
.log-list {
  display: flex;
  flex-direction: column;
  padding: 40rpx;
}
.log-item {
  margin: 10rpx;
}
//文件logs.json代码
{
  "navigationBarTitleText": "查看启动日志",
  "usingComponents": {}
}

相关其它博客

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(一)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(二)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(三)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(四)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(五)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(七)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

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

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

相关文章

【广州华锐互动】煤矿坍塌VR事故警示教育突破了哪些限制?

煤矿坍塌事故是煤矿行业的一种常见事故&#xff0c;对于矿工的生命安全和生产设备都存在着严重威胁。传统的安全培训方式往往难以真实地呈现事故场景&#xff0c;难以达到理想的安全教育效果。而虚拟现实&#xff08;VR&#xff09;技术的出现&#xff0c;为煤矿安全教育带来了…

测试人职场生存必须避开的5个陷阱

在互联网职场的工作发展道路上&#xff0c;软件测试人员其实在公司中也面临着各种各样的职场陷阱&#xff0c;有些可能是因为项目业务不熟练造成的&#xff0c;有些可能是自身技术能力不足导致的...等等。软件测试入门相对来说比较容易些&#xff0c;但是想要在测试行业长久发展…

力扣刷题-数组-数组理论基础

数组是存放在连续内存空间上的相同类型数据的集合。 需要两点注意的是 数组下标都是从0开始的。数组内存空间的地址是连续的 正是因为数组的在内存空间的地址是连续的**&#xff0c;所以我们在删除或者增添元素的时候&#xff0c;就难免要移动其他元素的地址。** 注意&…

S型加减速行车位置控制(支持点动和停靠位置搜索)

S型加减速位置控制详细算法和应用场景介绍&#xff0c;请查看下面文章博客。本篇文章不再赘述&#xff0c;这里主要介绍点动动和位置点搜索功能。 S速度曲线轨迹规划(普通变频位置闭环控制算法详细介绍SCL代码)_s曲线轨迹规划_RXXW_Dor的博客-CSDN博客位置控制用PD控制器&…

Rsync学习笔记2

Rsync&#xff1a; 增量操作&#xff1a; 1&#xff09; server01服务文件变动。 [rootserver03 tp5shop]# rsync -av /usr/local/nginx/html/tp5shop root192.168.17.109:/usr/local/nginx/html/ sending incremental file listsent 88,134 bytes received 496 bytes 177,…

KMP,ACM集训

目录 831. KMP字符串 输入格式 输出格式 数据范围 输入样例&#xff1a; 输出样例&#xff1a; 解析&#xff1a;KMP模板 D - Cyclic Nacklace 解析&#xff1a;KMP-next数组应用循环字符串判断 F - Power Strings 解析&#xff1a;KMP-next数组应用循环字符串判断 H - …

Haproxy负载均衡群集

HAproxy搭建Web群集一、Web集群调度器1、常见的Web集群调度器2、常用集群调度器的优缺点&#xff08;LVS ,Nginx,Haproxy)2.1 Nginx2.2 LVS2.3 Haproxy 3、LVS、Nginx、HAproxy的区别 二、Haproxy1、简介2、Haproxy应用分析3、HAProxy的主要特性4、Haproxy调度算法&#xff08;…

智慧云图书馆: 能支撑智慧图书馆服务体系的图书馆管理与服务平台

一、开源项目简介 柏拉图 PLATO 智慧云图书馆&#xff1a; 能支撑智慧图书馆服务体系的图书馆管理与服务平台。 二、开源协议 未使用主流开源协议 三、界面展示 四、功能概述 平台优势 总分馆架构&#xff1a;不再是信息的孤岛&#xff0c;而是共享信息的平台。友好的界…

openGauss学习笔记-76 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT简介

文章目录 openGauss学习笔记-76 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT简介76 MOT简介 openGauss学习笔记-76 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT简介 本节介绍了openGauss内存优化表&#xff08;Memory-Optimized Table&#xff0c;MOT…

spring-boot---validation,参数校验,分组,嵌套,各种类型

写在前面&#xff1a; 参数校验基本上是controller必做的事情&#xff0c;毕竟前端传过来的一切都不可信。 但是每次if(StrUtil.isNotNull())啥的有时候多还难写。validation可以简化这一操作。 文章目录 项目构建问题展示validation使用快速入门注释 Valid与Validated区别使…

【面试必刷TOP101】判断一个链表是否为回文结构 链表的奇偶重排

目录 题目&#xff1a;判断一个链表是否为回文结构_牛客题霸_牛客网 (nowcoder.com) 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;链表的奇偶重排_牛客题霸_牛客网 (nowcoder.com) 题目的…

Twitter图片数据优化的细节

Twitter个人数据优化&#xff1a;吸引更多关注和互动 头像照片在Twitter上&#xff0c;头像照片是最快识别一个账号的方法之一。因此&#xff0c;请务必使用公司的标志或与品牌相关的图片。建议尺寸为400x400像素。 为了建立强大的品牌形象和一致性&#xff0c;强烈建议在所有…

WebGL 初始化着色器

目录 前言 初始化着色器的7个步骤 创建着色器对象&#xff08;gl.createShader&#xff08;&#xff09;&#xff09; gl.createShader&#xff08;&#xff09;规范 gl.deleteShader&#xff08;&#xff09;规范 指定着色器对象的代码&#xff08;gl.shaderSource&…

大二层—多链接透明互联协议如何工作

大二层就引入了 TRILL&#xff08;Transparent Interconnection of Lots of Link&#xff09;&#xff0c;即多链接透明互联协议。它的基本思想是&#xff0c;二层环有问题&#xff0c;三层环没有问题&#xff0c;那就把三层的路由能力模拟在二层实现。 运行 TRILL 协议的交换…

23062QTday5

完成登录界面的注册功能 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QApplication> #include <iostream> #include <QMessageBox> #include <QtDebug> #include <QIcon> #include<QPushButton> #incl…

Leetcode—— 20.有效的括号

20. 有效的括号 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭…

【LeetCode-中等题】 222. 完全二叉树的节点个数

文章目录 题目方法一&#xff1a;把该题当做一个普通的二叉树来做&#xff08;任何遍历都可以&#xff09;方法二&#xff1a;利用完全二叉树的性质来做 题目 方法一&#xff1a;把该题当做一个普通的二叉树来做&#xff08;任何遍历都可以&#xff09; 例如&#xff1a;二叉树…

如何选择一只股票,待完善。

目录 ROE(盈利能力)增长率(成长能力)收现比(营收质量)总资产周转率(经营能力)增长率(成长能力)商誉净资产比(排雷)流动比率(排雷) ROE(盈利能力) 什么是ROE? ROE 全名叫 Return of Equity&#xff0c;翻成中文叫“股东回报率”&#xff0c;也叫"净资产收益率"。 …

token登录的实现

token登录的实现 我这种token只是简单的实现token&#xff0c;就是后端利用UUID 生成简单随机码&#xff0c;利用随机码作为在Redis中的键&#xff0c;然后存储的用户信息作为值&#xff0c;在每次合理请求的时候对token的有效时间进行刷新&#xff08;利用拦截器&#xff09;&…

常见的文件格式

一、C:\fakepath\新建文本文档.txt [object String] 实现方式&#xff1a; <input onchange"test(this.value)" type"file"></input><script>function test(e){console.log(e,Object.prototype.toString.call(e))}</script> 二、…