vue使用element-ui的el-upload上传图片至服务器,服务端使用的是node.js,图片上传成功,但界面显示不出来,是跨域问题?

图片不显示

我采用 vue+elementui+nodejs+mysql ,前台采用了潘家诚的vue-admin-template,后台采用 大事件后台API项目

看结果

img

看结果

img

看用户列表manager/index.vue代码

img

看后台app.js代码

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
const joi = require('@hapi/joi')

// 1.2 配置 cors 跨域,  导入 cors 中间件,必须在路由之前
const cors = require('cors')
// 将 cors 注册为全局中间件,这样项目中的接口就支持跨域访问了
app.use(cors())

// 1.3 配置解析表单数据的中间件 这是express 4.16+ 内置的,但这里没用,而是在下面使用了 bodyParser 解析 post 表单数据的中间件
// 内置中间件是基于bodyParser封装而来,两者用法基本一致
// (1) 通过如下的代码,配置解析(只能解析这种) application/x-www-form-urlencoded 格式的表单数据的中间件:
// app.use(express.urlencoded({ extended: false }))

// 1.4 在 app.js 中,所有路由之前,声明一个全局中间件,为 res 对象挂载一个 res.cc() 函数 :
// 在处理函数中,需要多次调用 res.send() 向客户端响应 处理失败 的结果,为了简化代码,可以手动封装一个 res.cc() 函数
app.use(function(req, res, next) {
  // status = 0 为成功; status = 1 为失败; 默认将 status 的值设置为 1,方便处理失败的情况
  res.cc = function (err, status=1, code=20000) {
    res.send({
      status,  // 状态
      code,
      message: err instanceof Error ? err.message : err,   // 状态描述,判断 err 是 错误对象 还是 字符串
    })
  }
  next()
})

// 1.5 解析 token 的中间件
const config = require('./config')   // 导入配置文件
const expressJWT = require('express-jwt')   // 解析 token 的中间件
// 使用 .unless({ path: [/^\/api\//] }) 指定哪些接口不需要进行 Token 的身份认证
app.use(expressJWT({ secret: config.jwtSecretKey }).unless({ path: [/^\/yan\//, /^\/public\//] }))

// 1.6 解析post的两个中间件  【一个星期的错误】为什么一直没能解析提交过来的data,是node服务端,body的中间件你没加上
//1.61.7都可以
// app.use(express.json())

// 1.7 解析 post 表单数据的中间件
const bodyParser = require('body-parser');
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// 配置解析,用于解析json和urlencoded格式的数据
app.use(bodyParser.json())

// 全局 中间件  解决所有路由的 跨域问题
app.all('*',function (req,res,next) {
  res.header("Access-Control-Allow-Origin: *")
  res.header("Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept,Authorization");
  res.header('Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,PATCH');
  next()
})

 //暴漏静态资源文件 暴漏之后我们可以通过域名访问该文件下的资源
 app.use(express.static('./public'))

// 1.8 实现图片上传
const multer = require('multer')
const fs = require("fs");
//图片上传
app.post("/public/user/fileUpload",
  multer({
    //设置文件存储路径
    dest: "./public/user/fileUpload",
  }).array("file", 1),
  function (req, res, next) {
    let files = req.files;
    let file = files[0];
    let fileInfo = {};
    // 这里去掉了目录中的public,因为上面指定public
    let path = "./public/user/fileUpload/" + Date.now().toString() + "_" + file.originalname;
    console.log(path);
    fs.renameSync("./public/user/fileUpload/" + file.filename, path);
    //获取文件基本信息
    fileInfo.type = file.mimetype;
    fileInfo.name = file.originalname;
    fileInfo.size = file.size;
    fileInfo.path = "http://127.0.0.1:3007"+path.replace(/.\/public/, '');
    // fileInfo.path = "http://127.0.0.1:9528"+path

    res.json({
      code: 200,
      msg: "OK",
      data: fileInfo,
    });
  }
);

// 2. 导入并使用【管理员】路由模块
const managerRouter = require('./router/manager')
app.use('/yan', managerRouter)

// 3. 导入并使用【个人中心】的用户信息路由模块
const userinfoRouter = require('./router/userinfo')
// 注意:以 /my 开头的接口,都是有权限的接口,需要进行 Token 身份认证
app.use('/my', userinfoRouter)

// 4. 导入并使用【文章分类】 的路由模块
const artCateRouter = require('./router/artcate')
// 为文章分类的路由挂载统一的访问前缀 /my/article
app.use('/my/article', artCateRouter)

// 5. 导入并使用【文章】 的路由模块
const articleRouter = require('./router/article')
app.use('/my/article', articleRouter)

// 6. 导入并使用【用户】 的路由模块
const userRouter = require('./router/user')
app.use('/my/user', userRouter)

// 9. 定义错误级别的中间件
// (1).捕获验证失败的错误,并把验证失败的结果响应给客户端
// (2).捕获并处理 Token 认证失败后的错误
app.use( (err, req, res, next) => {
  // 3.1 验证失败导致的错误
  if( err instanceof joi.ValidationError ) return res.cc(err)
  // 3.2 捕获身份认证失败后的错误
  if (err.name === 'UnauthorizedError') return res.cc('身份认证失败2!')
  // 3.3 否则就是未知的错误
  res.cc(err)

})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(3007, function () {
  console.log('api server running at http://127.0.0.1:3007')
})

看上传图片,成功了,但也是不显示,还是跨域问题?

img

出现问题的提示

img

看你这个最后报的BUG日志,应该还是浏览器跨域的问题。可以试试下面的方法:
方法一:
可以在后端 API 中添加响应头来允许跨域请求。比如在 Node.js 的 Express 框架中,使用以下代码来添加响应头:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

方法二:
可以在前端代码中使用代理服务器来解决这个问题。比如可以在vue.config.js中配置代理服务器,代码参考如下:

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
  }
}

这种就可以把所有以 "/api" 开头的请求转发到对应的网址上,并添加必要的响应头来允许跨域请求……

当然:以上都需要你先确定图片路径是否正确图片格式是否正确图片是否正确保存;确保这些都没有问题之后再去解决跨域的问题

希望可以帮到你

把文件上传的路径设置为静态资源 ,或者把文件目录用nginx代理下

在使用Vue和Element UI的el-upload组件上传图片到Node.js服务器时,确实可能会遇到跨域问题导致上传成功但无法在界面上显示的情况。解决跨域问题的方法有很多,其中一种常见的方法是使用CORS(跨源资源共享)来允许来自其他域的请求。以下是一些解决方案:在Node.js服务器上设置CORS中间件,允许来自Vue应用程序的跨域请求。可以使用第三方中间件,例如cors或者通过自己编写代码来实现。在Vue应用程序中配置代理,将所有的请求发送到与Vue应用程序相同的域,然后再将请求转发到Node.js服务器。这个可以通过在Vue.config.js文件中配置proxy来实现。在Element UI的el-upload组件上添加withCredentials属性,以便在发送跨域请求时携带Cookie信息。需要在Node.js服务器上设置Access-Control-Allow-Credentials响应头,允许来自Vue应用程序的请求携带Cookie信息。当然具体使用哪种方法取决于你的具体情况。

基于bing、GPT部分内容和本人思考总结:
是的,可能是跨域问题导致的。在使用el-upload上传图片时,如果服务器和客户端不在同一个域名下,就有可能出现跨域问题。具体表现为图片上传成功了,但是在界面上无法正常显示图片。
解决这个问题的方式有多种,以下是其中的一种方法:

在node.js服务器端设置响应头,允许跨域请求。可以使用cors中间件来实现:



plaintext
Copy code
const cors = require('cors')

app.use(cors())

这样可以允许所有来源的跨域请求,如果需要更加精细的控制,可以参考cors的文档进行配置。

在vue客户端中,设置el-upload组件的action属性为node.js服务器端的接口地址,同时设置headers属性,将Access-Control-Allow-Origin设置为*,即允许所有来源的跨域请求。示例代码如下:


plaintext
Copy code
<el-upload
  class="avatar-uploader"
  :action="uploadUrl"
  :headers="{ 'Access-Control-Allow-Origin': '*' }"
  :show-file-list="false"
  :on-success="handleUploadSuccess"
  :before-upload="beforeUpload">
  <img v-if="imageUrl" :src="imageUrl" class="avatar">
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

其中,uploadUrl为node.js服务器端的接口地址,handleUploadSuccess为上传成功后的回调函数,beforeUpload为上传前的回调函数。需要注意的是,设置headers属性时,应该将Access-Control-Allow-Origin设置为*,这样才能允许所有来源的跨域请求。如果需要更加精细的控制,可以在node.js服务器端进行设置。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
从问题描述中可以看出,图片上传到了服务器并返回了图片的访问路径,但是前端界面无法显示图片,这可能是跨域问题,也可能是图片路径不正确。

解决方案:

  1. 确认图片上传到了服务器指定的目录

在服务端代码中,在图片上传成功后,可以通过打印图片的访问路径和将该图片的路径返回给前端来确认图片是否上传到了服务器指定的目录。如果目录不正确或图片未上传成功,则无法在前端界面显示图片。

  1. 确认图片路径正确

在前端界面中,需要将图片的访问路径正确地绑定到标签的src属性中,以便浏览器可以正确地加载图片。通过浏览器的开发者工具可以查看请求的图片路径是否正确。如果图片路径不正确,则需要调整图片路径。

  1. 确认是否是跨域问题

通常跨域问题是指从一个域名的网页去请求另一个域名的资源时,浏览器会拒绝该请求,从而导致请求失败。但是在此问题中,是从同一个域名的网页上传图片到同一个域名的服务器上,所以可能不是跨域问题导致的。

如果确实是跨域问题,可以在服务端代码中启用cors模块来解决跨域问题,以便前端可以正确访问服务器的资源。

  1. 其他错误可能导致图片无法显示

图片路径不正确,文件类型不支持,网络不稳定等原因都可能导致图片无法显示。可以通过排查以上问题来确定问题的根本原因。
如果我的回答解决了您的问题,请采纳!

把返回的图片地址拿出来,直接在浏览器中访问,看图片能出来吗,先排除是不是图片路径的问题

问题描述:
使用vue和element-ui的el-upload组件上传图片至node.js服务器,上传成功,但是图片无法显示,出现跨域问题。
分析:
1. 跨域问题
根据问题描述和提示信息,可以初步判断是跨域问题导致的图片无法显示。在前端使用vue和element-ui的el-upload组件上传图片至node.js服务器时,由于前端和后端的域名不同,会触发跨域问题。虽然在后端已经使用了cors中间件解决了跨域问题,但是在前端上传图片时,需要在请求头中添加Access-Control-Allow-Origin字段,才能解决跨域问题。
2. 图片路径问题
另外,根据问题描述和提示信息,还可以初步判断是图片路径问题导致的图片无法显示。在上传图片成功后,后端返回的图片路径是"http://127.0.0.1:3007/public/user/fileUpload/xxxxx",但是在前端显示图片时,使用的是相对路径"./public/user/fileUpload/xxxxx",这样会导致图片无法显示。因此,需要在前端显示图片时,使用绝对路径"http://127.0.0.1:3007/public/user/fileUpload/xxxxx"。
解决方案:
1. 前端解决跨域问题
在前端上传图片时,需要在请求头中添加Access-Control-Allow-Origin字段,才能解决跨域问题。可以在el-upload组件的headers属性中添加Access-Control-Allow-Origin字段,如下所示:
class="avatar-uploader"
action="http://127.0.0.1:3007/public/user/fileUpload"
:headers="{ 'Access-Control-Allow-Origin': '*' }"
:show-file-list="false"
:on-success="handleSuccess"
:before-upload="beforeAvatarUpload">



2. 前端解决图片路径问题
在前端显示图片时,需要使用绝对路径"http://127.0.0.1:3007/public/user/fileUpload/xxxxx",而不是相对路径"./public/user/fileUpload/xxxxx"。可以在后端返回图片路径时,添加"http://127.0.0.1:3007"前缀,如下所示:
fileInfo.path = "http://127.0.0.1:3007" + path.replace(/.\\/public/, '');
这样,在前端显示图片时,就可以使用绝对路径"http://127.0.0.1:3007/public/user/fileUpload/xxxxx",从而解决图片路径问题。
总结:
在使用vue和element-ui的el-upload组件上传图片至node.js服务器时,需要注意跨域问题和图片路径问题。解决跨域问题可以在前端添加Access-Control-Allow-Origin字段,解决图片路径问题可以在后端返回图片路径时添加"http://127.0.0.1:3007"前缀。