探索前端图片如何携带token进行验证

文章介绍了如何在前端开发中创建一个名为tokenImg的组件,该组件支持显示和预览带有token的图片,以实现图片信息的安全传输。组件通过在图片URL或请求头中携带token,实现了身份验证和权限控制。组件包含预览和仅显示两种模式,使用下载文件API处理图片数据,并提供了预览图片列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

图片在前端开发中扮演了重要的角色,它们不仅仅是美观的元素,还可以传递信息和激发用户的兴趣。随着应用场景的增多,前端开发人员就需要在图片加载过程中携带验证的信息。如 token,用于身份验证、权限控制等方面。通过在图片的 URL 或请求头中携带 token 信息,从而实现图片信息的安全传输。


实现思路

  1. 创建一个名为 tokenImg 的组件,该组件用于显示图片并支持预览功能;
  2. 在组件的模板中,使用 <img> 标签来显示图片,或使用 element-ui<el-image> 标签进行图片预览;
  3. 在组件的属性中,接收图片的 URL 地址 (imgUrl)、图片类型 (imgType)、图片的宽度 (width) 和高度 (height);
  4. 在组件的数据中,定义预览图片列表 (previewList) 和预览图片路径 (previewpath);
  5. 实现两个方法 viewModel()preViewModel() 分别用于仅预览图片和带缩略图预览;
  6. viewModel() 方法中,通过调用下载文件的 API (downloadFileApi) 并根据返回的文件内容创建 URL 对象,将图片 URL 赋值给 <img> 标签的 src 属性;
  7. preViewModel() 方法中,同样调用下载文件的 API,将返回的文件内容创建 URL 对象,并将 URL 添加到预览图片列表中;
  8. 使用 watch 监听 imgUrl 属性的变化,在变化时根据 imgType 属性的值来调用对应的方法;
  9. 在组件的 mounted() 钩子中,根据初始的 imgType 属性值来调用对应的方法;
  10. main.js 文件中将 tokenImg 组件注册为全局组件,以便在其他地方使用;
  11. 在需要使用该组件的地方,使用 <TokenImg> 标签,并传递相应的属性(如图片 URL、图片类型、宽度和高度);
    这样,你可以在前端中使用 tokenImg 组件来显示带有 Token 的图片,并支持预览功能。注意确保在组件使用时传递正确的图片 URL、类型、宽度和高度。

封装文件

<template>
  <div>
    <!-- 显示图片 -->
    <img ref="img" :style="{width:width,height:height}" v-if="imgType == 'view'" />
    <!-- 使用element-ui的el-image进行图片预览 -->
    <el-image :style="{width:width,height:height}" ref="previewimg" v-if="imgType == 'preView'" :src="previewpath"
      :preview-src-list="previewList"></el-image>
  </div>
</template>
<script>
// 引入的接口文件
import { downloadFileApi } from "@/api/publicApi/enumeration";
export default {
  name: "token-img",
  props: {
    // 图片的URL地址
    imgUrl: {
      type: String,
    },
    // 图片类型,可选为'view'(仅预览图片)或'preView'(可点击预览)
    imgType: {
      type: String,
      default: "view",
    },
    // 图片的宽度
    width: {
      type: String,
    },
    // 图片的高度
    height: {
      type: String,
    },
  },
  data() {
    return {
      // 预览图片列表
      previewList: [],
      // 预览图片路径
      previewpath: "",
    };
  },
  methods: {
    //仅预览图片
    viewModel() {
      const img = this.$refs.img;
      // 调用下载文件的API并根据返回的文件内容创建URL对象
      downloadFileApi(this.imgUrl).then((res) => {
        img.src = URL.createObjectURL(res);
        img.onload = () => {
          URL.revokeObjectURL(img.src);
        };
      });
    },
    //带缩略图预览
    preViewModel() {
      downloadFileApi(this.imgUrl).then((res) => {
        // 调用下载文件的API并根据返回的文件内容创建URL对象
        this.previewpath = URL.createObjectURL(res);
        this.previewList.push(this.previewpath);
      });
    },
  },
  watch: {
    // 监听imgUrl变化
    imgUrl() {
      if (this.imgType == "view") {
        this.viewModel();
      } else if (this.imgType == "preView") {
        this.preViewModel();
      }
    },
  },
  mounted() {
    if (this.imgType == "view") {
      this.viewModel();
    } else if (this.imgType == "preView") {
      this.preViewModel();
    }
  },
};
</script>

引入的接口文件

responseType: "blob" 表示希望以二进制形式接收响应数据。这在处理文件下载或者需要以二进制形式处理响应数据的情况下非常有用。通过将 responseType 设置为 blob,可以确保响应数据以 blob对象的形式返回,然后可以进一步处理或者保存到本地。

export function downloadFileApi(imgUrl) {
  return request({
    url: "/api/file/examine-preview"+imgUrl,
    method: "get",
    responseType: "blob",
  });
}

main.js

// 将其注册为全局组件
import TokenImg from "@/components/tokenImg";
Vue.component('TokenImg', TokenImg)

使用文件

<TokenImg :width="`50px`" :height="`50px`" :imgUrl="YourUrl" :imgType="`preView`"/>

实现效果

发起请求

在这里插入图片描述

渲染查看

在这里插入图片描述


拓展

一、微信小程序中实现该操作

封装文件 ---- .js

// 引入服务器请求封装的模块
const server = require('../../utils/server.js');
Component({
  // 组件的内部数据
  data: {
    previewPath: "", // 预览图片路径
  },
  // 组件的对外属性,是属性名到属性设置的映射表
  properties: {
    imgUrl: { // 图片的URL地址
      type: null,
      observer: 'fetchData' // 监听imgUrl属性的变化,触发fetchData方法
    },
    imageWidth: { // 图片的宽度
      type: String,
    },
    imageHeight: { // 图片的高度
      type: String,
    },
  },
  // 组件的方法,包括事件响应函数和任意的自定义方法
  methods: {
    // 发起请求获取图片数据
    fetchData() {
      let {
        imgUrl
      } = this.properties;
      console.log(imgUrl);
      if (typeof imgUrl === 'string') {
        imgUrl = [imgUrl]; // 如果是字符串,转化为数组
      }
      // 处理多张图片
      const imagePromises = imgUrl.map(url => {
        return new Promise((resolve, reject) => {
          const imageUrl = `http://192.168.0.6666/${url}`;
          server.request({
            url: imageUrl,
            responseType: 'arraybuffer',
            success: (res) => {
              const base64 = wx.arrayBufferToBase64(res.data);
              resolve(`data:image/png;base64,${base64}`);
            },
            fail: (error) => {
              reject(error);
            }
          });
        });
      });
      // 处理多张图片的 Promise
      Promise.all(imagePromises)
        .then(images => {
          this.setData({
            previewPath: images,
          });
        })
        .catch(error => {
          console.error(error);
        });
    },

    // 点击预览图片
    previewImageOn(e) {
      const {
        previewpath
      } = e.target.dataset; // 解构获取预览图片URL
      wx.previewImage({ // 调用微信预览图片的API
        urls: [previewpath], // 需要预览的图片URL列表
      });
    },
  }
});

封装文件 ---- .wxml

<view>
  <block wx:for="{{previewPath}}" wx:for-index="index">
    <image bindtap="previewImageOn" data-previewPath="{{item}}" src="{{item}}" mode="aspectFill" 
    style="width:{{imageWidth}};height:{{imageHeight}};" key="{{index}}" />
  </block>
</view>

app.json 全局引入

"usingComponents": {
  "token-img": "./components/tokenImg/tokenImg"
},

page.json 全局引入

{
    "usingComponents": {
        "token-img": "./components/tokenImg/tokenImg"
    }
}

使用文件

<token-img imageWidth="100%" imageHeight="170rpx" imgUrl="{{details.tailImg}}"></token-img>

实现效果

在这里插入图片描述


二、下载文件携带 token

第一种方式:手写实现

//下载方法
getBgdzByGcsj(row) {
  // 通过接口下载文件
  downloadFileApiDown(row.bgdz).then((res) => {
    // 将文件流转换为下载链接
    const downloadUrl = URL.createObjectURL(res);
    // 创建一个<a>标签
    const link = document.createElement("a");
    // 设置链接的URL为下载链接
    link.href = downloadUrl;
    // 设置下载的文件名为"报表管理.xls"
    link.download = "报表管理.xls";
    // 隐藏<a>标签
    link.style.display = "none";
    // 将<a>标签添加到页面的<body>中
    document.body.appendChild(link);
    // 触发<a>标签的点击事件,开始下载
    link.click();
    // 下载完成后删除<a>标签
    document.body.removeChild(link);
  });
}

第二种方式:使用插件(file-saver

file-saver 是一个 JavaScript 库,用于在浏览器中保存文件。它提供了一种简单的方法来生成并保存文件,而不需要服务器参与。使用 file-saver 插件,你可以轻松地在前端生成和下载文件,无需发送文件请求到服务器和返回文件链接,大大简化了文件下载的过程。

file-saver 插件的主要功能是将通过 Blob 对象生成的文件下载链接保存到浏览器的下载路径中。它提供了以下几种方法:

1. saveAs 方法

保存文件到本地。你可以使用 saveAs 方法来指定文件的内容和名称,然后将其保存到浏览器的下载路径。

2. save 方法

保存文件到本地,与 saveAs 方法类似,但不会弹出文件保存对话框。

3. createObjectURL 方法

创建 Blob 对象的 URL。通过 createObjectURL 方法,你可以将 Blob 对象转换为可供下载的 URL

4. revokeObjectURL 方法

释放之前创建的 URL。一旦文件下载完成,你可以使用 revokeObjectURL 方法来释放已经创建的 URL,以释放浏览器资源。

  • 安装

    npm install file-saver
    
  • 引入

    import { saveAs } from 'file-saver';
    
  • 使用

    // res 返回地址
    saveAs(res, '报表管理.xls');
    
<think>好的,我需要回答用户关于前端登录验证的实现方法或解决方案的问题。首先,我要确保回答符合用户的要求,结构清晰,并且引用站内的内容。根据用户提供的引用,有两个相关的资源:[^1]提到了单点登录的前端实现,使用Cookies设置特定域名的cookie;[^2]是关于大文件上传的断点续传,虽然主要是文件上传,但可能涉及到验证机制,比如在分块上传时的身份验证。 首先,我需要整理前端登录验证的基本流程。通常包括表单提交、数据验证、与后端API交互、处理令牌或Cookie、状态管理等步骤。然后结合用户提供的引用,单点登录的实现可以通过设置跨域Cookie来实现,如引用[^1]中的例子,使用Cookies.set方法设置特定域名的cookie,这样用户在访问其他子域时也能保持登录状态。这可能需要在用户登录成功后,后端返回token前端将其存储在cookie中,并指定domain属性为顶级域名,确保各个子域都能读取该cookie。 另外,用户提到的引用[^2]虽然主要是文件上传,但其中提到的分块上传可能需要验证用户身份,每次上传分块时都需要携带token,这可能涉及到在请求头中添Authorization字段,使用Bearer token的方式。这可以与登录验证流程结合,确保用户在上传文件时已经通过身份验证。 接下来,我需要考虑其他常见的登录验证方案,比如JWT(JSON Web Token)的使用,以及前端如何安全地存储token(例如使用HttpOnly的Cookie,或者结合localStorage和内存中的变量)。同时,需要提到安全措施,如防止XSS和CSRF攻击,使用HTTPS等。 然后,根据用户的需求生成相关问题,这些问题应该与登录验证相关,可能包括单点登录的具体实现、第三方登录集成、安全优化措施、token刷新机制等。需要确保这些问题能够引导用户进一步探索相关主题。 在组织回答时,要保持结构清晰,分点说明每个步骤或方案,并自然地融入引用内容。例如,在讲解单点登录时引用,在讲解API请求的身份验证时引用中关于分块上传时携带标识符的方法,类比到token的使用。 最后,检查是否符合系统级指令,如使用正确的中文,数学表达式的格式(虽然这个问题可能不涉及数学公式,但如果有变量或代码,要正确使用格式),以及引用标识的正确添。确保回答真实可靠,不引入错误的信息。</think>### 前端登录验证实现方法及解决方案 #### 1. **基础登录验证流程** - **表单提交与验证** 用户在前端输入账号密码后,通过表单提交到后端验证前端需进行基础格式校验(如非空、邮箱格式、密码强度),例如: ```javascript if (!username || !password) { alert('账号或密码不能为空'); return; } ``` - **API请求与响应处理** 使用`fetch`或`axios`发送登录请求,后端返回`token`或`session`标识: ```javascript axios.post('/login', { username, password }) .then(response => { localStorage.setItem('token', response.data.token); }); ``` 引用[^2]中提到的分块上传机制也需类似验证,每次请求需携带身份标识(如`token`)。 #### 2. **身份状态管理** - **Token存储与安全** - 推荐使用`HttpOnly Cookie`存储`token`,防止XSS攻击。 - 或结合`localStorage`存储`token`,但需防范XSS(如避免直接渲染未转义内容)。 - **全局状态同步** 使用`React Context`、`Vuex`或`Redux`管理登录状态,确保组件间同步。 #### 3. **单点登录(SSO)实现** 跨子域名的单点登录可通过设置共享Cookie实现,如引用中的示例: ```javascript Cookies.set('auth_token', 'xxx', { domain: '.example.com' }); // 顶级域名 ``` 用户访问`a.example.com`或`b.example.com`时均可读取此Cookie实现自动登录。 #### 4. **第三方登录集成** - **OAuth2.0/OpenID Connect** 集成微信、Google等第三方登录,前端需重定向到第三方授权页,例如: ```javascript window.location.href = 'https://oauth.provider.com?client_id=xxx&redirect_uri=xxx'; ``` - **回调处理** 第三方登录成功后,前端解析URL中的`code`参数并发送到后端换取`token`。 #### 5. **安全增强措施** - **CSRF防护** 后端返回`CSRF Token`,前端在请求头中附(如`X-CSRF-TOKEN`)。 - **请求密** 敏感数据(如密码)使用HTTPS传输,前端可对密码进行客户端哈希(需与后端协商方案)。 #### 6. **Token自动刷新** 临近过期时,通过`refresh_token`静默获取新`token`: ```javascript axios.post('/refresh-token', { refresh_token: storedToken }) .then(response => { localStorage.setItem('token', response.data.new_token); }); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水星记_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值