Vue项目部署IIS全攻略:从构建到上线,解决路由与跨域难题

发布时间:2026/8/7 14:02:53
Vue项目部署IIS全攻略:从构建到上线,解决路由与跨域难题 1. 项目概述从Vue打包到IIS上线的完整旅程最近在帮一个朋友的公司处理一个前后端分离的项目上线后端是.NET Core API前端是Vue 3 Vite部署环境是Windows Server。他们之前一直用Node.js跑开发服务器一到生产环境就卡壳了特别是IIS的配置踩了不少坑。这其实是一个非常典型的场景开发时一切顺风顺水npm run dev跑得飞快跨域用个代理就解决了但一旦要部署到IIS这种“企业级”Web服务器上各种404、500、空白页、跨域失败的问题就接踵而至。这不仅仅是把dist文件夹扔进去那么简单它涉及到IIS角色安装、应用程序池配置、URL重写规则、MIME类型还有Vue项目本身的路由模式、环境变量和构建配置的深度适配。如果你也正面临类似情况手头有一个打包好的Vue项目需要在Windows Server的IIS上让它“活”起来并且稳定运行那么这篇从零开始的实战记录或许能帮你省下大量排查时间。我会从最基础的IIS安装讲起覆盖所有关键配置步骤并重点剖析那些最容易出错的环节比如history路由模式下的404问题、vue.config.js中环境变量和代理配置在构建后的失效问题以及令人头疼的跨域CORS配置。整个过程我会尽量说清楚“为什么要这么做”而不仅仅是“怎么做”。2. 环境准备与IIS安装配置在开始部署之前确保你有一个干净的Windows Server环境如Windows Server 2016/2019/2022或Windows 10/11专业版/企业版用于本地测试。IISInternet Information Services是Windows自带的Web服务器但默认不安装。2.1 安装IIS及相关功能模块很多人安装IIS只勾选默认的Web服务器这会导致后续缺少关键功能。我们需要的是一个能良好支持现代前端应用尤其是SPA的IIS环境。打开服务器管理器在Windows Server上通常桌面就有这个图标。在Windows 10/11上可以搜索“启用或关闭Windows功能”。添加角色和功能在服务器管理器中选择“添加角色和功能”。选择安装类型一路点击“下一步”直到“服务器角色”页面。关键角色选择在“Web服务器IIS”角色前打勾此时会弹出窗口询问是否添加所需功能点击“添加功能”。深入功能选择重中之重选中“Web服务器IIS”后不要急着点下一步点击右下角的“下一步”进入“功能”页面前先点击“Web服务器角色IIS”旁边的“”展开然后选择“角色服务”。这里需要勾选以下关键服务基本功能默认已选保持即可。应用程序开发这是核心必须勾选.NET Extensibility 3.5、.NET Extensibility 4.8根据你的.NET版本、ASP.NET 3.5/4.8、ISAPI扩展、ISAPI筛选器。即使你的Vue项目不直接使用.NET但IIS的许多底层功能和后续可能用到的URL重写模块依赖这些环境。性能和健康诊断建议勾选“HTTP日志”和“请求监视器”便于后期排查。安全性根据需求选择如“请求筛选”、“IP限制”等。常见HTTP功能确保“静态内容”、“默认文档”、“目录浏览”建议不勾选出于安全考虑、“HTTP错误”已选。完成安装继续点击“下一步”直至“安装”等待安装完成。可能需要重启。注意如果是在已有IIS的服务器上操作可以通过“添加角色和功能”来补充安装缺失的“角色服务”无需重装整个IIS。2.2 安装URL重写模块关键步骤Vue Router使用history模式时所有非根路径的请求如/about,/user/profile在刷新或直接访问时IIS会试图在物理路径下寻找对应的文件或文件夹显然找不到于是返回404。解决这个问题的标准方案是使用URL重写将所有非文件请求重定向到入口文件index.html。IIS默认不包含URL重写模块需要单独下载安装。下载访问微软官方下载页面搜索“IIS URL Rewrite Module Download”下载与你的系统架构x86/x64匹配的安装包。安装以管理员身份运行安装程序。安装过程很简单一路下一步即可。验证安装完成后打开IIS管理器运行inetmgr点击任意一个站点在中间的功能视图区应该能看到一个名为“URL重写”的图标。如果没有尝试重启IIS管理器或服务器。这个模块是我们解决SPA路由问题的核心工具。3. Vue项目构建与关键配置解析部署前我们需要一个生产环境构建的Vue项目。通常使用npm run build或yarn build。这个命令会在项目根目录下生成一个dist文件夹里面就是我们需要部署到IIS的静态文件。然而构建过程本身有很多配置会直接影响部署结果必须在构建前确认。3.1 理解vue.config.js的构建时与运行时这是最容易混淆的地方。vue.config.js中的很多配置如devServer.proxy仅在开发服务器npm run dev运行时生效。当你执行npm run build时这些配置不会被打包进dist文件。这意味着开发环境的代理跨域配置在构建后完全失效。你的前端代码在浏览器中发起的API请求会直接指向你配置的target而不再是开发服务器的代理。如果API服务器地址与前端部署地址不同源就会立刻触发浏览器的跨域限制。解决方案生产环境的跨域问题必须在后端API服务器或前端部署的Web服务器IIS上配置CORS策略而不是在前端构建配置里。我们稍后在IIS配置部分会详细说明。3.2 环境变量与全局配置你可能会在vue.config.js或.env文件中定义环境变量比如API的基础地址VUE_APP_API_BASE_URL。// vue.config.js module.exports { // ... 其他配置 // 这个配置只在构建时起作用 chainWebpack: config { config.plugin(define).tap(args { args[0][process.env].VUE_APP_API_BASE_URL JSON.stringify(process.env.VUE_APP_API_BASE_URL || https://api.yourdomain.com); return args; }); } }或者使用.env.production文件VUE_APP_API_BASE_URLhttps://api.yourdomain.com构建时注入在运行npm run build时这些环境变量的值会被“写死”到生成的静态文件如app.xxxxxx.js中。构建完成后再修改变量文件或系统环境变量是没用的。部署注意事项因此在CI/CD流水线中你需要在构建步骤就传入正确的生产环境变量值。如果后端API地址在部署后才能确定这种硬编码的方式就不够灵活。更动态的方案是将基础路径配置为一个相对路径如/api然后通过IIS的URL重写或反向代理功能将/api的请求转发到真实的API服务器。这样前端代码就无需关心API的绝对地址。3.3 路由模式与publicPath在router/index.js中确认路由模式const router createRouter({ history: createWebHistory(process.env.BASE_URL), // history 模式 // 或者 createWebHashHistory() // hash 模式 routes, })Hash模式 (#): 如http://yourdomain.com/#/about。这种模式下路由变化不会触发浏览器向服务器发起页面请求因此部署最简单几乎兼容所有服务器无需特殊配置。但URL不够美观。History模式: URL更简洁美观如http://yourdomain.com/about。但需要服务器端支持这就是为什么我们必须安装和配置IIS的URL重写模块。在vue.config.js中publicPath配置也很重要module.exports { publicPath: process.env.NODE_ENV production ? /your-sub-path/ : /, // 如果你的应用部署在子路径下 }如果Vue应用不是部署在网站根目录例如你想通过http://yourdomain.com/app/访问就必须正确设置publicPath为/app/否则资源JS, CSS, 图片的加载路径会出错。完成以上检查和配置后执行构建命令得到一个准备就绪的dist文件夹。4. IIS站点部署与核心配置实战现在我们将dist文件夹里的内容部署到IIS。4.1 创建网站与应用程序池打开IIS管理器。创建应用程序池可选但推荐在左侧连接面板右键点击“应用程序池”选择“添加应用程序池”。名称可以设为你的项目名例如MyVueAppPool。.NET CLR版本选择“无托管代码”。因为Vue是纯静态文件不需要.NET运行时。托管管道模式选择“集成”。这通常性能更好与URL重写等模块兼容性更佳。添加网站在左侧连接面板右键点击“站点”选择“添加网站”。网站名称填写易于识别的名称如MyVueApp。物理路径指向你dist文件夹的完整路径例如C:\WebSites\MyVueApp\dist。确保IIS进程用户默认是IIS_IUSRS对该路径有读取权限。绑定类型http或httpsIP地址“全部未分配”端口80HTTP或443HTTPS。主机名如果你有域名就填写。应用程序池选择刚才创建的MyVueAppPool。设置默认文档点击新创建的站点在功能视图区找到“默认文档”。确保index.html存在于列表中并且位置靠前。如果没有就右键“添加”输入index.html。至此一个最基本的静态网站就配置好了。你可以通过绑定的IP和端口访问应该能看到Vue应用的首页。但是如果你使用的是history路由模式点击页面内的路由链接可以正常跳转但一旦刷新页面或直接访问子路由路径就会得到404错误。接下来就是解决这个核心问题。4.2 配置URL重写规则解决History模式404这是部署SPA到IIS最关键的一步。在IIS管理器中选中你的Vue应用站点。在功能视图区双击打开“URL重写”模块。在右侧“操作”面板点击“添加规则”。选择“空白规则”然后点击“确定”。现在配置规则名称输入一个描述如SPA Fallback。匹配URL请求的URL选择“与模式匹配”。模式输入*一个星号。这意味着匹配所有URL。忽略大小写勾选。条件重要点击“添加”条件。条件输入{REQUEST_FILENAME}。检查是否“不是文件”。点击“添加”第二个条件。条件输入{REQUEST_FILENAME}。检查是否“不是目录”。逻辑分组选择“全部匹配”。这两个条件的意思是只有当请求的URL既不对应一个物理存在的文件也不对应一个物理存在的目录时才应用此规则。这样就能保证对像/static/js/app.js这类真实静态资源的请求不会被错误重写。服务器变量留空。操作操作类型选择“重写”。重写URL输入/index.html。追加查询字符串勾选。点击右侧“应用”保存规则。这个规则的工作原理是当用户访问/about时IIS会先检查物理路径下是否存在about文件或文件夹。因为不存在所以满足“不是文件且不是目录”的条件于是规则触发将请求内部重写到/index.html。Vue应用被加载后Vue Router会解析浏览器地址栏中的/about并渲染对应的组件从而实现了路由的恢复。4.3 配置静态文件缓存与MIME类型性能优化为了提高性能我们可以为静态资源如JS、CSS、图片设置客户端缓存。在站点功能视图区找到“HTTP响应标头”双击打开。在右侧“操作”面板点击“设置常用标头”。勾选“使Web内容过期”并设置为“之后”时间可以设为例如“7.00:00:00”7天。这样浏览器会在一定时间内缓存这些资源减少重复请求。MIME类型现代前端构建工具生成的文件通常都有正确的扩展名IIS默认能识别。但如果你的项目引入了某些特殊类型的文件如.webp图片、.woff2字体而IIS不认识导致无法访问就需要手动添加。在站点根目录或dist文件夹上右键选择“属性”或直接在站点功能视图找“MIME类型”添加对应的扩展名和MIME类型即可。5. 生产环境跨域CORS问题终极解决方案如前所述vue.config.js中的devServer.proxy只在开发时有用。生产环境下前端代码运行在用户的浏览器中直接向后端API假设是https://api.otherdomain.com发起fetch或axios请求时会因为“同源策略”被浏览器拦截。解决方案有三个层次推荐使用方案二或三5.1 方案一后端配置CORS最标准这是最规范、最安全的做法。在你的后端API服务器如ASP.NET Core, Node.js Express, Java Spring等的响应头中添加CORS策略。例如在ASP.NET Core中// Program.cs builder.Services.AddCors(options { options.AddPolicy(AllowMyApp, policy { policy.WithOrigins(https://your-vue-app-domain.com) // 你的前端域名 .AllowAnyMethod() .AllowAnyHeader(); }); }); app.UseCors(AllowMyApp);这样当浏览器发起跨域请求时后端会返回Access-Control-Allow-Origin: https://your-vue-app-domain.com等头部浏览器就会允许此次请求。5.2 方案二IIS作为反向代理推荐解决同源如果前后端部署在同一台服务器或内网且你希望浏览器认为所有请求都来自同一个源从而避免CORS可以使用IIS的“应用程序请求路由”和“URL重写”模块配合将前端的API请求代理到后端服务器。安装ARR模块和安装URL重写模块类似需要下载并安装“Application Request Routing”。启用代理安装后在IIS根节点服务器级别的功能视图会出现“应用程序请求路由缓存”。打开它进入“服务器代理设置”勾选“启用代理”。在Vue站点添加代理规则回到你的Vue站点打开“URL重写”模块添加一条新的规则。模式^api/(.*)假设所有API请求以/api开头。条件通常不需要额外条件。操作类型“重写”。重写URLhttp://your-api-server:port/{R:1}。{R:1}捕获了(.*)部分。勾选“停止处理后续规则”。修改前端请求基址将你前端代码中所有API请求的基址改为相对路径/api。例如原本请求https://api.server.com/users现在改为请求/api/users。这样浏览器发起到/api/users的请求IIS会将其透明地转发到http://your-api-server:port/users并将响应返回给浏览器。对浏览器而言请求始终发生在https://your-vue-app-domain.com这个源下完美规避了跨域问题。同时前端代码也无需硬编码后端地址部署更灵活。5.3 方案三IIS配置CORS模块直接添加响应头如果后端不方便修改或者请求的第三方API本身不支持CORS可以尝试在IIS层面为响应添加CORS头。但这通常只对简单请求有效对于需要预检Preflight的复杂请求可能不够。下载并安装“IIS CORS Module”。安装后在站点或全局的“配置编辑器”中找到system.webServer/cors节点进行配置或者直接修改web.config文件。强烈建议优先让后端配置CORS方案一这是最符合Web标准的做法。如果条件允许使用IIS反向代理方案二也是一个非常优雅的解决方案它将跨域问题在服务器层面消化掉了。6. 部署常见问题与报错深度排查即使按照上述步骤操作仍然可能遇到各种问题。下面是一些常见报错及其排查思路。6.1 错误代码 403.14 - Forbidden目录列表被禁用现象访问网站根目录返回403错误。原因IIS找不到默认文档如index.html并且目录浏览被禁用。排查检查站点物理路径是否正确index.html文件是否存在。检查“默认文档”设置确保index.html在列且启用。检查文件权限确保IIS_IUSRS或应用程序池标识对dist文件夹有读取权限。少见检查请求筛选规则是否屏蔽了.html扩展名。6.2 错误代码 404.0 - Not FoundHistory路由问题现象直接访问子路由或刷新页面时出现404。原因URL重写规则未生效或配置错误。排查确认URL重写模块已正确安装。检查为站点配置的URL重写规则是否存在条件是否配置正确必须是“不是文件”且“不是目录”。可以尝试暂时将规则模式改为(.*)并去掉所有条件进行测试。如果能正常访问再逐步加上条件调试。检查应用程序池的“托管管道模式”是否为“集成”模式。经典模式可能与URL重写模块工作不正常。6.3 错误代码 500.19 - Internal Server Error配置错误现象任何访问都返回500.19错误信息可能涉及web.config。原因web.config文件格式错误或包含了IIS无法识别的配置节。排查检查站点根目录下的web.config文件可能是Vue项目自带的也可能是URL重写模块自动生成的。用文本编辑器打开检查XML格式是否正确标签是否闭合等。如果你手动编辑过web.config重点检查system.webServer节下的rewrite、handlers等配置。一个常见的坑是如果你从其他地方复制了配置可能包含了未安装模块对应的配置节比如cors但你没安装CORS模块。注释掉或删除未使用的配置节。6.4 静态资源JS/CSS/图片加载失败404现象页面空白或样式错乱浏览器控制台提示JS/CSS文件404。原因资源路径错误。排查检查vue.config.js中的publicPath配置。如果应用部署在子路径如/app/publicPath必须是/app/不能是/。查看浏览器开发者工具的“网络”选项卡看失败的资源请求的完整URL是什么与服务器上的实际路径对比。检查IIS中是否为此类静态文件如.js,.css配置了正确的MIME类型通常不需要但可检查。检查URL重写规则是否过于宽泛错误地重写了静态资源的请求。确保规则中“不是文件”和“不是目录”的条件正常工作。6.5 跨域请求被阻止CORS Policy现象页面运行正常但调用API时浏览器控制台报错Access to fetch at ‘https://api.xxx.com‘ from origin ‘https://yourdomain.com‘ has been blocked by CORS policy。原因生产环境未配置CORS。排查确认你使用的是方案一后端配置、方案二IIS代理还是方案三IIS CORS模块。如果是方案一打开浏览器开发者工具查看API请求的“响应头”中是否包含Access-Control-Allow-Origin: https://yourdomain.com。如果没有说明后端配置未生效。如果是方案二检查反向代理规则是否生效。可以尝试在服务器上直接访问http://localhost/your-api-path如果IIS和API在同一台机器看是否能通过IIS代理访问到后端。对于复杂请求如Content-Type为application/json的POST请求浏览器会先发送一个OPTIONS方法的预检请求。你需要确保后端或IIS也能正确处理OPTIONS请求并返回正确的CORS头。6.6 应用程序池自动停止崩溃现象网站间歇性无法访问事件查看器中能看到应用程序池因“快速失败保护”而停止。原因应用程序池中运行的进程虽然我们托管的是静态文件但IIS仍有工作进程短时间内多次崩溃。排查检查应用程序池的“高级设置”。将“.NET CLR版本”设置为“无托管代码”“启用32位应用程序”设置为False如果是64位系统。检查站点物理路径的权限确保应用程序池标识默认是IIS AppPool\你的程序池名有读取和执行权限。检查服务器内存和CPU资源是否充足。暂时禁用“快速失败保护”进行测试不推荐生产环境长期禁用。部署是一个系统工程尤其是将现代化的前端框架部署到传统的IIS服务器上需要打通从构建、服务器配置到网络策略的每一个环节。我的经验是严格按照流程操作并理解每一步背后的原理遇到问题时从浏览器控制台、IIS日志位于%SystemDrive%\inetpub\logs\LogFiles和Windows事件查看器中寻找线索层层分解绝大多数问题都能找到解决方案。最后在正式上线前务必在测试环境进行完整的流程演练。