【发布时间】:2020-10-01 21:12:49
【问题描述】:
我正在创建一个 MERN 应用程序,我是新手。我尝试在网上学习一些教程,但遇到了一些错误。
我正在提交这样的发布请求。如您所见,我没有指定内容类型,因为我知道如果您使用'multipart/form-data,它会自动将其附加到标题中。我在这里使用了一个反应钩子,这就是为什么我不直接使用 fetch 方法。
const formData = new FormData();
formData.append("email", formState.inputs.email.value);
formData.append("name", formState.inputs.name.value);
formData.append("password", formState.inputs.password.value);
formData.append("image", formState.inputs.image.value);
const responseData = await sendRequest(
`${process.env.REACT_APP_BACKEND_BASE_URL}/api/users/signup`,
"POST",
formData
);
同时我的注册路线是这样的,在 user-routes.js 下
router.post(
"/signup",
fileUpload.single("image"),
[
check("name").not().isEmpty(),
check("email")
.normalizeEmail() // Test@test.com => test@test.com
.isEmail(),
check("password").isLength({ min: 6 }),
],
usersController.signup
);
您也可以看到,我正在使用fileUpload.single("image") 在路线中捕获它
如果您需要查看我在这里使用的钩子,那就是,但我很确定该钩子可以正常工作。它没有任何问题,所以这里是:这是一个反应钩子
export const useHttpClient = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState();
const activeHttpRequests = useRef([]);
const sendRequest = useCallback(
async (url, method = "GET", body = null, headers = {}) => {
setIsLoading(true);
const httpAbortCtrl = new AbortController();
activeHttpRequests.current.push(httpAbortCtrl);
try {
const response = await fetch(url, {
method,
body,
headers,
signal: httpAbortCtrl.signal,
});
const responseData = await response.json();
// console.log("Response: ", response);
// console.log("Data: ", responseData);
activeHttpRequests.current = activeHttpRequests.current.filter(
(reqCtrl) => reqCtrl !== httpAbortCtrl
);
if (!response.ok) {
throw new Error(responseData.message);
}
setIsLoading(false);
return responseData;
} catch (err) {
setError(err.message);
setIsLoading(false);
throw err;
}
},
[]
);
const clearError = () => {
setError(null);
};
useEffect(() => {
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
activeHttpRequests.current.forEach((abortCtrl) => abortCtrl.abort());
};
}, []);
return { isLoading, error, sendRequest, clearError };
};
我将在此处包含我的 users.controller 的注册:
const signup = async (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next(
new HttpError("Invalid inputs passed, please check your data.", 422)
);
}
const { name, email, password } = req.body;
let existingUser;
try {
existingUser = await User.findOne({ email: email });
} catch (err) {
const error = new HttpError(
"Signing up failed, please try again later.",
500
);
return next(error);
}
if (existingUser) {
const error = new HttpError(
"User exists already, please login instead.",
422
);
return next(error);
}
let hashedPassword;
try {
hashedPassword = await bcrypt.hash(password, 12);
} catch (err) {
const error = new HttpError(
"Could not create user, please try again.",
500
);
return next(error);
}
//res.json({ message: "AFTER HASHING" });
const createdUser = new User({
name,
email,
image: req.file.path,
password: hashedPassword,
places: [],
});
try {
await createdUser.save();
} catch (err) {
const error = new HttpError(
"Signing up failed, please try again later.",
500
);
return next(error);
}
let token;
try {
token = jwt.sign(
{ userId: createdUser.id, email: createdUser.email },
process.env.JWT_KEY,
{ expiresIn: "1h" }
);
} catch (err) {
const error = new HttpError(
"Signing up failed, please try again later.",
500
);
return next(error);
}
res
.status(201)
.json({ userId: createdUser.id, email: createdUser.email, token: token });
};
【问题讨论】:
-
您实际上返回的是 HTML 而不是 JSON。您必须收到 HTTP 错误,例如404.
const response等待promise解析后的结果,不是JSON字符串。所以这失败了......const responseData = await response.json(); -
@Mr.Polywhirl 不,我没有返回任何 html,我从这里读到,如果您发送的内容类型为“multiform”,而您提交的数据是 json,则会遇到这种情况对象,这里是 URL:stackoverflow.com/questions/50432928/…
-
@IvanApungan 有一个非常简单的方法可以找出答案:查看浏览器开发人员工具(“网络”选项卡)中的实际 HTTP 响应正文。请注意,正如 Polywhirl 先生所说,无论您的代码是否返回 HTML,您的服务器都可以返回 HTML 格式的错误。
-
@Pointy 是的,他是正确的,似乎服务器正在返回 html 或文本类型,但我没有在注册路线中出错,我假设问题出在 multer .我正在使用 multer 上传文件
-
@Pointy 似乎我部署的服务器正在返回内部服务器错误状态代码 500,我在注册功能的每个场景中都使用了 try catch,但错误就在其中。我认为错误甚至在它进入注册块之前就发生了,也许它在我在 user-routes.js 中导入的 fileupload.js 文件中
标签: javascript reactjs multer