Node.js 用户配置文件的图像未返回
我正在尝试更新用户图像,但每当用户名输入更改时,图像就会消失。 默认情况下会生成用户名。 如果输入值中存在相同的用户名,则可以正常工作。 例如:我将userby username生成为kmmujfli34,即使我更改了一个字符,也会得到错误 这就是我在控制台中遇到的错误Node.js 用户配置文件的图像未返回,node.js,mongodb,express,user-input,next.js,Node.js,Mongodb,Express,User Input,Next.js,我正在尝试更新用户图像,但每当用户名输入更改时,图像就会消失。 默认情况下会生成用户名。 如果输入值中存在相同的用户名,则可以正常工作。 例如:我将userby username生成为kmmujfli34,即使我更改了一个字符,也会得到错误 这就是我在控制台中遇到的错误 GET http://localhost:8000/api/user/photo/kmmujfli34ss 400 (Bad Request) 这是我用于更新个人资料和保存照片的后端代码 exports.update = (r
GET http://localhost:8000/api/user/photo/kmmujfli34ss 400 (Bad Request)
这是我用于更新个人资料和保存照片的后端代码
exports.update = (req, res) => {
let form = new formidable.IncomingForm();
form.keepExtension = true;
form.parse(req, (err, fields, files) => {
if (err) {
return res.status(400).json({
error: 'Photo could not be uploaded'
});
}
let user = req.profile;
// user's existing role before update
let existingRole = user.role;
let existingEmail = user.email;
if (fields && fields.username && fields.username.length > 12) {
return res.status(400).json({
error: 'Username should be less than 12 characters long'
});
}
if (fields.username) {
fields.username = slugify(fields.username).toLowerCase();
}
if (fields.password && fields.password.length < 6) {
return res.status(400).json({
error: 'Password should be min 6 characters long'
});
}
user = _.extend(user, fields);
// user's existing role - dont update - keep it same
user.role = existingRole;
user.email = existingEmail;
if (files.photo) {
if (files.photo.size > 10000000) {
return res.status(400).json({
error: 'Image should be less than 1mb'
});
}
user.photo.data = fs.readFileSync(files.photo.path);
user.photo.contentType = files.photo.type;
}
user.save((err, result) => {
if (err) {
console.log('profile udpate error', err);
return res.status(400).json({
error: errorHandler(err)
});
}
user.hashed_password = undefined;
user.salt = undefined;
user.photo = undefined;
res.json(user);
});
});
};
exports.photo = (req, res) => {
const username = req.params.username;
User.findOne({ username }).exec((err, user) => {
if (err || !user) {
return res.status(400).json({
error: 'User not found'
});
}
if (user.photo.data) {
res.set('Content-Type', user.photo.contentType);
return res.send(user.photo.data);
}
});
};
组成部分
import Link from 'next/link';
import { useState, useEffect } from 'react';
import Router from 'next/router';
import { getCookie, isAuth } from '../../actions/auth';
import { getProfile, update } from '../../actions/user';
import { API } from '../../config';
const ProfileUpdate = () => {
const [values, setValues] = useState({
username: '',
name: '',
email: '',
about: '',
password: '',
error: false,
success: false,
loading: false,
photo: '',
userData: ''
});
const token = getCookie('token');
const { username, name, email, about, password, error, success, loading, photo, userData } = values;
const init = () => {
getProfile(token).then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
username: data.username,
name: data.name,
email: data.email,
about: data.about
});
}
});
};
useEffect(() => {
init();
}, []);
const handleChange = name => e => {
// console.log(e.target.value);
const value = name === 'photo' ? e.target.files[0] : e.target.value;
let userFormData = new FormData();
userFormData.set(name, value);
setValues({ ...values, [name]: value, userData: userFormData, error: false, success: false });
};
const handleSubmit = e => {
e.preventDefault();
setValues({ ...values, loading: true });
update(token, userData).then(data => {
if (data.error) {
setValues({ ...values, error: data.error, success: false, loading: false });
} else {
setValues({
...values,
username: data.username,
name: data.name,
email: data.email,
about: data.about,
password: '',
success: true,
loading: false
});
}
});
};
const profileUpdateForm = () => (
<form onSubmit={handleSubmit}>
<div className="form-group">
<label className="btn btn-outline-info">
Profile photo
<input onChange={handleChange('photo')} type="file" accept="image/*" hidden />
</label>
</div>
<div className="form-group">
<label className="text-muted">Username</label>
<input onChange={handleChange('username')} type="text" value={username} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">Name</label>
<input onChange={handleChange('name')} type="text" value={name} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">Email</label>
<input onChange={handleChange('email')} type="text" value={email} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">About</label>
<textarea onChange={handleChange('about')} type="text" value={about} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">Password</label>
<input onChange={handleChange('password')} type="password" value={password} className="form-control" />
</div>
<div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</div>
</form>
);
const showError = () => (
<div className="alert alert-danger" style={{ display: error ? '' : 'none' }}>
{error}
</div>
);
const showSuccess = () => (
<div className="alert alert-success" style={{ display: success ? '' : 'none' }}>
Profile updated
</div>
);
const showLoading = () => (
<div className="alert alert-info" style={{ display: loading ? '' : 'none' }}>
Loading...
</div>
);
return (
<React.Fragment>
<div className="container">
<div className="row">
<div className="col-md-4">
<img
src={`${API}/user/photo/${username}`}
className="img img-fluid img-thumbnail mb-3"
style={{ maxHeight: 'auto', maxWidth: '100%' }}
alt="user profile"
/>
</div>
<div className="col-md-8 mb-5">
{showSuccess()}
{showError()}
{showLoading()}
{profileUpdateForm()}
</div>
</div>
</div>
</React.Fragment>
);
};
export default ProfileUpdate;
从“下一个/链接”导入链接;
从“react”导入{useState,useEffect};
从“下一个/路由器”导入路由器;
从“../../actions/auth”导入{getCookie,isAuth};
从“../../actions/user”导入{getProfile,update};
从“../../config”导入{API};
常量配置文件更新=()=>{
const[values,setValues]=useState({
用户名:“”,
名称:“”,
电子邮件:“”,
关于:'',
密码:“”,
错误:false,
成功:错,
加载:false,
照片:'',
用户数据:“”
});
const-token=getCookie('token');
const{username,name,email,about,password,error,success,load,photo,userData}=value;
常量init=()=>{
getProfile(令牌)。然后(数据=>{
if(data.error){
setValues({…值,错误:data.error});
}否则{
设定值({
价值观
用户名:data.username,
name:data.name,
电子邮件:data.email,
关于:data.about
});
}
});
};
useffect(()=>{
init();
}, []);
const handleChange=name=>e=>{
//console.log(如target.value);
const value=name==“photo”?e.target.files[0]:e.target.value;
让userFormData=new FormData();
userFormData.set(名称、值);
setValues({…values,[名称]:value,userData:userFormData,error:false,success:false});
};
常量handleSubmit=e=>{
e、 预防默认值();
setValues({…值,加载:true});
更新(令牌、用户数据)。然后(数据=>{
if(data.error){
setValues({…values,error:data.error,success:false,load:false});
}否则{
设定值({
价值观
用户名:data.username,
name:data.name,
电子邮件:data.email,
关于:data.about,
密码:“”,
成功:没错,
加载:错误
});
}
});
};
const profileUpdateForm=()=>(
个人资料照片
用户名
名称
电子邮件
关于
密码
提交
);
常数r=()=>(
{错误}
);
const showSuccess=()=>(
档案更新
);
常量showLoading=()=>(
加载。。。
);
返回(
{showSuccess()}
{showError()}
{showLoading()}
{profileUpdateForm()}
);
};
导出默认配置文件更新;
'忽略这些行,因为stackoverflow需要添加更多详细信息,因为其中大部分是代码`
import Link from 'next/link';
import { useState, useEffect } from 'react';
import Router from 'next/router';
import { getCookie, isAuth } from '../../actions/auth';
import { getProfile, update } from '../../actions/user';
import { API } from '../../config';
const ProfileUpdate = () => {
const [values, setValues] = useState({
username: '',
name: '',
email: '',
about: '',
password: '',
error: false,
success: false,
loading: false,
photo: '',
userData: ''
});
const token = getCookie('token');
const { username, name, email, about, password, error, success, loading, photo, userData } = values;
const init = () => {
getProfile(token).then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
username: data.username,
name: data.name,
email: data.email,
about: data.about
});
}
});
};
useEffect(() => {
init();
}, []);
const handleChange = name => e => {
// console.log(e.target.value);
const value = name === 'photo' ? e.target.files[0] : e.target.value;
let userFormData = new FormData();
userFormData.set(name, value);
setValues({ ...values, [name]: value, userData: userFormData, error: false, success: false });
};
const handleSubmit = e => {
e.preventDefault();
setValues({ ...values, loading: true });
update(token, userData).then(data => {
if (data.error) {
setValues({ ...values, error: data.error, success: false, loading: false });
} else {
setValues({
...values,
username: data.username,
name: data.name,
email: data.email,
about: data.about,
password: '',
success: true,
loading: false
});
}
});
};
const profileUpdateForm = () => (
<form onSubmit={handleSubmit}>
<div className="form-group">
<label className="btn btn-outline-info">
Profile photo
<input onChange={handleChange('photo')} type="file" accept="image/*" hidden />
</label>
</div>
<div className="form-group">
<label className="text-muted">Username</label>
<input onChange={handleChange('username')} type="text" value={username} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">Name</label>
<input onChange={handleChange('name')} type="text" value={name} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">Email</label>
<input onChange={handleChange('email')} type="text" value={email} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">About</label>
<textarea onChange={handleChange('about')} type="text" value={about} className="form-control" />
</div>
<div className="form-group">
<label className="text-muted">Password</label>
<input onChange={handleChange('password')} type="password" value={password} className="form-control" />
</div>
<div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</div>
</form>
);
const showError = () => (
<div className="alert alert-danger" style={{ display: error ? '' : 'none' }}>
{error}
</div>
);
const showSuccess = () => (
<div className="alert alert-success" style={{ display: success ? '' : 'none' }}>
Profile updated
</div>
);
const showLoading = () => (
<div className="alert alert-info" style={{ display: loading ? '' : 'none' }}>
Loading...
</div>
);
return (
<React.Fragment>
<div className="container">
<div className="row">
<div className="col-md-4">
<img
src={`${API}/user/photo/${username}`}
className="img img-fluid img-thumbnail mb-3"
style={{ maxHeight: 'auto', maxWidth: '100%' }}
alt="user profile"
/>
</div>
<div className="col-md-8 mb-5">
{showSuccess()}
{showError()}
{showLoading()}
{profileUpdateForm()}
</div>
</div>
</div>
</React.Fragment>
);
};
export default ProfileUpdate;