现象
刷新单页应用时,vue报错resource interpreted as Stylesheet but transferred with MIME type text/html

解决步骤
1. nginx类型匹配配置
- 根据错误提示,这是服务端无法正确解析css的MIME类型造成的。
- 因此首先想到的是nginx配置是否正确,检查发现nginx配置没问题,与文件类型有关的配置如下:
http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为text/plain
}
排除该原因。
2. 单页面应用history模式nginx配置
- 由于所做vue项目是单页面应用,因此刷新失败无法加载,考虑是否是配置404没有返回index页导致,根据官网配置,也没有问题
location / {
try_files $uri $uri/ /index.html;
}
- 注释掉vue-router中的mode:'history’再构建项目也可以排除history模式404配置问题
3. css引入方式改写
默认的css引入方式为:
<link rel="stylesheet" href="//xxx.css">
增加可识别类型:
<link rel="stylesheet" type='text/css' href="//xxx.css">
无法解决问题。默认css引入方式都已经支持,不大可能因此报错,排除该原因。
4. vue/cli@3构建配置
上述报错的css路径形式为:
https://blog.feroad.com/admin/css/index.hash.css
怀疑路径不对,手动尝试更改为:
https://blog.feroad.com/css/index.hash.css
可以访问到压缩混淆后的css,这说明是路径错误。即vue/cli构建工具构建相对路径生成css导致的错误。检查vue.config.js发现:
module.exports = {
baseUrl: process.env.NODE_ENV === 'production' ? './' : '/', // ./表示相对目录 /表示绝对目录
}
这段代码删掉即可解决问题。
问题反思
以下代码是手动加入vue.config.js文件中,使得yarn build后的项目能够直接在本地打开,它是自己每个vue项目初始化时使用的“小聪明”,它只在简单项目中没有问题。
baseUrl: process.env.NODE_ENV === 'production' ? './' : '/', // ./表示相对目录 /表示绝对目录
但在router中存在嵌套路由或者动态路由等“两层”以上的路由时,相对路径生成最终css包将导致路径错误。如下子路由:
<!--router.js-->
{
path: '/admin',
name: 'admin',
component: Admin,
children: [{
path: '/admin/delete',
name: 'delete',
component: AdminDelete
},
{
path: '/admin/release',
name: 'release',
component: AdminRelease
}]
}
将造成AdminRelease组件中的css构建相对于host/admin的文件路径时候,生成的可访问css的路径错误,生成:
https://blog.feroad.com/admin/css/index.hash.css
而实际上/admin/这层并不应该出现。这个错误不容易发现。
结论与引申
因此,不要轻易改变vue工具的默认配置,除非明确了解修改配置造成的副作用。
-
尽管build后的文件不能本地打开,但可以使用本地node服务或者测试服务器去验证,不建议直接打开本地文件
-
在axios使用时,用到拦截器功能,请求拦截器将请求想JSON.stringify(data)再发送。这造成了使用FormData对象上传文件时无法发送file对象。因此需要判断request.data是否是FormData的实例再考虑是否stringify。
axios.interceptors.request.use(
request => {
if (request.method === 'post' && !(request.data instanceof FormData)) {
request.data = Qs.stringify(request.data);
return request;
}
return request;
},
error => {
return Promise.reject(error);
}
);
- 将vue渐进式引入老项目,逐步替换为vue模块的学习方法存在问题。应直接按照vue的思想去实践,上全家桶。
- 如vue在构建单页面应用很成熟,而使用单页面与多页面混合应用来解决加载速度的问题,并且共用了vuex和router时,加载速度问题没解决,反而造成了每个单页加载内容过多,项目整体不规范的后果
- 使用vue单页+nuxt服务端渲染这样规范的方案来解决加载速度和SEO的问题,不要“发明轮子”。
评论 2