云计算百科
云计算领域专业知识百科平台

VUE项目部署IIS服务器手册

IIS部署Vue项目完整手册

📋 目录

  • 基础概念
  • 准备工作
  • Vue项目构建
  • web.config详解
  • IIS部署步骤
  • 不同场景配置
  • 常见问题
  • 实用配置模板

  • 基础概念

    Vue单页应用(SPA)工作原理

    重要理解:Vue项目是单页应用,这意味着:

    • 物理层面:整个项目只有一个HTML文件(index.html)

    • 逻辑层面:用户看到多个"页面",实际上是JavaScript动态切换内容

    • 路由处理:所有路由跳转都由Vue Router在前端处理

      当用户直接访问 http://yoursite.com/about 时:

    • 没有web.config:

      用户访问 /about → IIS寻找 about.html 文件 → 找不到 → 404错误

    • 有web.config重写规则:

      用户访问 /about → IIS找不到about.html → web.config规则生效 → 返回index.html → Vue Router接管,显示about页面

    用户看到的:
    /home -> 首页
    /about -> 关于页面
    /products -> 产品页面
    /contact -> 联系页面

    实际服务器文件:
    dist/
    ├── index.html ← 只有这一个HTML文件!
    ├── css/
    ├── js/
    └── assets/

    路由模式对比

    路由模式URL格式IIS配置需求说明
    Hash模式 /#/home 无需配置 兼容性好,但URL不美观
    History模式 /home 必须配置 URL美观,需要服务器支持

    准备工作

    环境要求

    • Node.js:版本 14+
    • Vue CLI:最新版本
    • IIS:Windows Server 2016+ 或 Windows 10+
    • URL Rewrite模块:必须安装

    安装Vue CLI

    # 全局安装Vue CLI
    npm install -g @vue/cli

    # 验证安装
    vue –version

    检查IIS URL Rewrite

  • 打开IIS管理器
  • 选择服务器节点
  • 查看是否有"URL 重写"图标
  • 如果没有,请下载安装:URL Rewrite 2.1

  • Vue项目构建

    创建新项目

    # 创建项目
    vue create my-vue-project

    # 选择配置
    ? Please pick a preset:
    Default ([Vue 3] babel, eslint)
    ❯ Default ([Vue 2] babel, eslint)
    Manually select features

    # 进入项目目录
    cd my-vue-project

    # 开发测试
    npm run serve

    构建生产版本

    # 构建项目
    npm run build

    # 构建完成后会生成dist文件夹
    dist/
    ├── index.html
    ├── css/
    ├── js/
    ├── img/
    └── favicon.ico

    配置自动生成web.config

    方法1:在public文件夹中创建(推荐)

    在项目的 public/ 文件夹中创建 web.config 文件,构建时会自动复制到 dist/。

    方法2:在vue.config.js中配置

    // vue.config.js
    const { defineConfig } = require('@vue/cli-service')

    module.exports = defineConfig({
    transpileDependencies: true,

    // 配置基础路径(如果部署在子目录)
    publicPath: process.env.NODE_ENV === 'production' ? '/myapp/' : '/',

    // 自定义构建过程
    configureWebpack: {
    plugins: [
    {
    apply: (compiler) => {
    compiler.hooks.emit.tapAsync('CopyWebConfig', (compilation, callback) => {
    const webConfigContent = `<?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
    </rules>
    </rewrite>
    </system.webServer>
    </configuration>
    `
    ;

    compilation.assets['web.config'] = {
    source: () => webConfigContent,
    size: () => webConfigContent.length
    };
    callback();
    });
    }
    }
    ]
    }
    })


    web.config详解

    核心重写规则解析

    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" /> <!– 1. 匹配所有URL路径 –>
    <conditions logicalGrouping="MatchAll">
    <!– 2. 检查请求的不是真实存在的文件 –>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <!– 3. 检查请求的不是真实存在的文件夹 –>
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <!– 4. 如果以上条件都满足,重写到根目录 –>
    <action type="Rewrite" url="/" />
    </rule>

    翻译成人话:如果用户访问的不是真实存在的文件或文件夹,就给他返回首页(index.html),让Vue Router来处理。

    执行逻辑:

  • 用户访问 /about

  • IIS检查服务器上是否有 about.html 文件 → 没有

  • IIS检查服务器上是否有 about/ 文件夹 → 没有

  • 触发重写规则,返回 index.html

  • Vue Router接管,显示about页面内容

    无论您的Vue项目有多少个界面,这个重写规则都不用变!

    因为:

    • 10个界面 → 还是只有1个index.html
    • 100个界面 → 还是只有1个index.html
    • 1000个界面 → 还是只有1个index.html

    所有界面的切换都是Vue Router在前端JavaScript中处理的。

  • 重要概念

    • stopProcessing=“true”:匹配到此规则后停止处理后续规则
    • negate=“true”:条件取反,即"不是文件"的意思
    • {REQUEST_FILENAME}:IIS服务器变量,表示请求的文件路径

    IIS部署步骤

    第一步:复制文件

    # 将dist文件夹内容复制到IIS目录
    # 例如:C:\\inetpub\\wwwroot\\myvueapp\\

    第二步:创建IIS网站

  • 打开IIS管理器
  • 右键"网站" → “添加网站”
  • 配置网站信息:
    • 网站名称:Vue-App
    • 物理路径:C:\\inetpub\\wwwroot\\myvueapp
    • 端口:80 或其他可用端口
    • 主机名:(可选)
  • 第三步:配置应用程序池

  • 选择应用程序池
  • 高级设置:
    • .NET CLR版本:无托管代码
    • 托管管道模式:集成
    • 启用32位应用程序:False
  • 第四步:设置权限

  • 右键网站文件夹
  • 属性 → 安全
  • 添加 IIS_IUSRS 用户
  • 权限:读取和执行、列出文件夹目录、读取
  • 第五步:启动网站

  • 在IIS中选择网站
  • 右键 → 管理网站 → 启动
  • 测试访问:http://localhost:端口号

  • 不同场景配置

    场景1:基础Vue项目(最常用)

    适用:简单的展示型网站,前后端分离,后端API已部署

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
    </rules>
    </rewrite>
    </system.webServer>
    </configuration>

    场景2:前后端同服务器部署

    架构示例:

    服务器(192.168.1.100)
    ├── IIS网站1 (端口80) ← Vue前端
    │ └── C:\\inetpub\\wwwroot\\vue-app\\
    └── IIS网站2 (端口5000) ← .NET后端API
    └── C:\\inetpub\\wwwroot\\api\\

    Vue项目API调用:

    // 在Vue项目中直接调用后端API
    axios.get('http://192.168.1.100:5000/api/users')

    web.config:使用基础配置即可

    场景3:前后端不同服务器 + API代理

    架构示例:

    前端服务器(192.168.1.100) 后端服务器(192.168.1.200)
    ├── IIS ├── IIS/Apache/Nginx
    │ └── Vue项目 │ └── API服务

    优势:前端无需知道后端真实地址,避免跨域问题

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <!– API代理规则 – 必须放在前面 –>
    <rule name="Proxy to API" stopProcessing="true">
    <match url="^api/(.*)" />
    <action type="Rewrite" url="http://192.168.1.200:5000/api/{R:1}" />
    </rule>

    <!– Vue路由规则 –>
    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
    </rules>
    </rewrite>
    </system.webServer>
    </configuration>

    Vue项目API调用:

    // 简化的API调用,会被自动代理
    axios.get('/api/users') // 实际访问:http://192.168.1.200:5000/api/users

    场景4:子目录部署

    部署路径:http://domain.com/myapp/

    vue.config.js配置:

    module.exports = {
    publicPath: '/myapp/'
    }

    web.config配置:

    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/myapp/" /> <!– 修改这里 –>
    </rule>

    场景5:企业级生产环境

    特点:高安全性、高性能、多环境支持

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.webServer>
    <!– URL重写规则 –>
    <rewrite>
    <rules>
    <!– 强制HTTPS –>
    <rule name="Redirect to HTTPS" stopProcessing="true">
    <match url="(.*)" />
    <conditions>
    <add input="{HTTPS}" pattern="off" ignoreCase="true" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
    redirectType="Permanent" />

    </rule>

    <!– API代理 –>
    <rule name="API Proxy" stopProcessing="true">
    <match url="^api/(.*)" />
    <action type="Rewrite" url="https://api.company.com/{R:1}" />
    </rule>

    <!– Vue路由 –>
    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
    </rules>
    </rewrite>

    <!– 安全头 –>
    <httpHeaders>
    <add name="X-Frame-Options" value="SAMEORIGIN" />
    <add name="X-Content-Type-Options" value="nosniff" />
    <add name="X-XSS-Protection" value="1; mode=block" />
    <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
    <add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
    <add name="Content-Security-Policy" value="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" />
    </httpHeaders>

    <!– 缓存策略 –>
    <staticContent>
    <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="31536000" />
    </staticContent>

    <!– 启用压缩 –>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" />

    <!– 自定义错误页面 –>
    <httpErrors errorMode="Custom">
    <remove statusCode="404" subStatusCode="-1" />
    <error statusCode="404" path="/" responseMode="ExecuteURL" />
    <remove statusCode="500" subStatusCode="-1" />
    <error statusCode="500" path="/error.html" responseMode="ExecuteURL" />
    </httpErrors>
    </system.webServer>
    </configuration>


    常见问题

    问题1:HTTP 错误 500.19 – MIME类型冲突

    错误信息:

    在唯一密钥属性"fileExtension"设置为".js"时,无法添加类型为"mimeMap"的重复集合项

    解决方案:

    <!– 方法1:移除staticContent配置(推荐) –>
    <!– 直接删除 <staticContent> 部分 –>

    <!– 方法2:先移除再添加 –>
    <staticContent>
    <remove fileExtension=".js" />
    <mimeMap fileExtension=".js" mimeType="application/javascript" />
    </staticContent>

    问题2:页面刷新后404错误

    原因:缺少URL重写规则

    解决方案:确保web.config包含完整的重写规则

    问题3:CSS/JS文件加载失败

    原因:文件路径或权限问题

    解决方案:

  • 检查文件是否完整复制
  • 确认IIS_IUSRS权限
  • 检查publicPath配置
  • 问题4:API调用跨域错误

    解决方案:

  • 在web.config中配置API代理
  • 在后端API中配置CORS
  • 使用nginx反向代理
  • 问题5:子目录部署路径错误

    解决方案:

  • 修改vue.config.js中的publicPath
  • 修改web.config中的重写目标
  • 确保路由配置正确

  • 实用配置模板

    模板1:开发/测试环境

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <!– 开发API代理 –>
    <rule name="Dev API" stopProcessing="true">
    <match url="^api/(.*)" />
    <action type="Rewrite" url="http://localhost:3000/api/{R:1}" />
    </rule>

    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
    </rules>
    </rewrite>

    <!– 开发环境允许跨域 –>
    <httpHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
    </httpHeaders>
    </system.webServer>
    </configuration>

    模板2:生产环境(安全优化)

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <!– 强制HTTPS –>
    <rule name="Force HTTPS" stopProcessing="true">
    <match url="(.*)" />
    <conditions>
    <add input="{HTTPS}" pattern="off" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
    </rule>

    <!– 生产API –>
    <rule name="Production API" stopProcessing="true">
    <match url="^api/(.*)" />
    <action type="Rewrite" url="https://api.production.com/{R:1}" />
    </rule>

    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
    </rules>
    </rewrite>

    <!– 安全头 –>
    <httpHeaders>
    <add name="X-Frame-Options" value="DENY" />
    <add name="X-Content-Type-Options" value="nosniff" />
    <add name="X-XSS-Protection" value="1; mode=block" />
    <add name="Strict-Transport-Security" value="max-age=31536000" />
    </httpHeaders>

    <!– 缓存优化 –>
    <staticContent>
    <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="604800" />
    </staticContent>
    </system.webServer>
    </configuration>

    模板3:多环境切换

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <!– 开发环境API(手动启用/禁用) –>
    <rule name="Dev API" enabled="false" stopProcessing="true">
    <match url="^api/(.*)" />
    <action type="Rewrite" url="http://localhost:3000/api/{R:1}" />
    </rule>

    <!– 测试环境API –>
    <rule name="Test API" enabled="false" stopProcessing="true">
    <match url="^api/(.*)" />
    <action type="Rewrite" url="https://test-api.company.com/{R:1}" />
    </rule>

    <!– 生产环境API –>
    <rule name="Prod API" enabled="true" stopProcessing="true">
    <match url="^api/(.*)" />
    <action type="Rewrite" url="https://api.company.com/{R:1}" />
    </rule>

    <rule name="Handle History Mode and hash fallback" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
    </rules>
    </rewrite>
    </system.webServer>
    </configuration>


    部署检查清单

    部署前检查

    • Vue项目构建成功(npm run build)
    • dist文件夹包含所有文件
    • web.config文件已创建
    • IIS已安装URL Rewrite模块

    部署时检查

    • 文件复制到正确位置
    • IIS网站配置正确
    • 应用程序池设置正确
    • 文件权限设置正确

    部署后检查

    • 网站可以正常访问
    • 路由跳转正常
    • 页面刷新不出现404
    • API调用正常
    • 静态资源加载正常

    性能优化建议

    1. 启用压缩

    <urlCompression doStaticCompression="true" doDynamicCompression="true" />

    2. 设置缓存

    <staticContent>
    <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="2592000" />
    </staticContent>

    3. 优化构建

    // vue.config.js
    module.exports = {
    productionSourceMap: false, // 禁用source map
    configureWebpack: {
    optimization: {
    splitChunks: {
    chunks: 'all'
    }
    }
    }
    }


    总结

  • 理解SPA原理:Vue是单页应用,所有路由都要重定向到index.html
  • 核心配置不变:无论多少页面,基本的重写规则都一样
  • 按需添加功能:根据具体需求添加API代理、安全头等配置
  • 环境区分部署:开发、测试、生产使用不同的配置
  • 注意执行顺序:web.config规则从上到下执行,注意stopProcessing属性
  • 通过本手册,您可以根据具体情况快速选择合适的配置模板,实现Vue项目在IIS上的成功部署!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » VUE项目部署IIS服务器手册
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!