【问题标题】:doesn't work send in res.status(409).send('error')不起作用发送 res.status(409).send('error')
【发布时间】:2019-09-01 05:21:29
【问题描述】:

当状态码为 200 时,我的后端(节点 js)正确地向前端发送数据,但当状态码不是 200 时,不要向前端发送任何内容

前端代码:

handleSubmit = async (e) => {
    try {
        e.preventDefault()
        const result = await createPost(JSON.parse(JSON.stringify(this.state)))
        console.log(result) // ==> if status code !== 200 => result=undefined 
        if (result.status === 200) toast.success('پست با موفقیت ساخته شد')

    } catch (ex) {
        console.log(ex)
        if (ex.response && ex.response.status === 400)
            toast.error('لطفا کلیه موارد را پر کنید');
    }
}

后端代码

router.post('/', auth, async (req, res) => {
    const { error } = validate(req.body);
    if (error) return res.status(400).send(error.details[0].message);

    let post = new Post({
        postTitle: req.body.postTitle,
        postImageUrl: req.body.postImageUrl,
        postContent: req.body.postContent,
        postTags: req.body.postTags
    });

    post = await post.save();

    res.status(200).send(post);
});

如果后端响应状态不是 200,我希望运行 catch 部分, 但当状态码为 400 ex.response 且 ex.response.status 未定义时。

当我运行它时,我在浏览器中的控制台会记录以下消息:

POST http://localhost:3800/api/post 400(错误请求)

createPost.jsx:19 未定义

createPost.jsx:23 TypeError: 无法读取属性“状态” 不明确的 在 CreatePost.handleSubmit (createPost.jsx:20)

我的验证函数是:

const validate = post => {
    const schema = {
        postTitle: Joi.string().required(),
        postDate: Joi.string(),
        postImageUrl: Joi.string(),
        postContent: Joi.string().required(),
        postTags: Joi.array(),
        postLike: Joi.number()
    };

    return Joi.validate(post, schema);
};

我的创建帖子组件是:

import React, { Component } from 'react';
import { createPost } from '../../services/postService'
import { toast } from 'react-toastify';
import _ from 'lodash'

class CreatePost extends Component {
    state = {
        postTitle: '',
        postImageUrl: '',
        postContent: '',
        postTags: []
    }

    handleSubmit = async (e) => {
        try {
            e.preventDefault()

            const result = await createPost(JSON.parse(JSON.stringify(this.state)))
            console.log(result) // ==> if status code !== 200 => result=undefined 
            if (result.status === 200) toast.success('پست با موفقیت ساخته شد')

        } catch (ex) {
            console.log(ex)
            if (ex.response && ex.response.status === 400)
                toast.error('لطفا کلیه موارد را پر کنید');
        }
    }

    render() {
        return (
            <form
                className="form-group bg-light border rounded m-2 shadow p-5"
                onSubmit={this.handleSubmit}
            >
                <label className="col-md-4 control-label" htmlFor="txtTitle">
                    عنوان پست
                </label>
                <input
                    id="txtTitle"
                    name="postTitle"
                    type="text"
                    placeholder="عنوان"
                    className="form-control input-md m-2"
                    value={this.state.postTitle}
                    onChange={e => this.setState({ postTitle: e.target.value })}
                />

                <input
                    id="txtImageUrl"
                    name="postImageUrl"
                    type="text"
                    placeholder="لینک عکس (الزامی نیست)"
                    className="form-control input-md m-2"
                    value={this.state.postImageUrl}
                    onChange={e =>
                        this.setState({ postImageUrl: e.target.value })
                    }
                />

                <textarea
                    name="postContent"
                    className="form-control m-2"
                    rows="5"
                    placeholder="متن پست"
                    value={this.state.postContent}
                    onChange={e =>
                        this.setState({ postContent: e.target.value })
                    }
                />

                <label className="col-md-4 control-label" htmlFor="txtTags">
                    برچسب ها
                </label>

                <input
                    id="txtTags"
                    name="postTags"
                    type="text"
                    placeholder="برچسب را با (,) از هم جدا کنید"
                    className="form-control input-md m-2"
                    value={this.state.postTags}
                    onChange={e =>
                        this.setState({
                            postTags: _.split(e.target.value, ',')
                        })
                    }
                />

                <button className="btn btn-success m-5">ساخت پست جدید</button>
            </form>
        );
    }
}

export default CreatePost;

创建后服务是:

export function createPost(post) {
    return http.post(config.api_post, post)
}

http 服务是: 从'axios'导入axios 从 'react-toastify' 导入 { toast }

axios.defaults.headers.common['x-auth-token']=localStorage.getItem('token')

axios.interceptors.response.use(null, error => {
    const expectedError =
        error.response &&
        error.response.status >= 400 &&
        error.response.status < 500

    if (!expectedError){
        console.log('Logging the error:', error)
        toast.error('خطایی رخ داده است')

        return Promise.reject(error)        
    }
})

export default {
    get: axios.get,
    post: axios.post,
    put: axios.put,
    delete: axios.delete,
    patch: axios.patch
}

这个 github 存储库是: https://github.com/mehdiparastar/personal-site.git

如何解决这个问题?

【问题讨论】:

  • 不是本次导入的组件import { createPost } from '../../services/postService'

标签: node.js reactjs


【解决方案1】:

问题在于您的axios.interceptor。通常,如果您在 await axios 上使用 try/catch,则 http 4xx 错误会转到 catch 块。但是你已经拦截并改变了行为。

在您的拦截器逻辑中,expectedError 将评估为 true 用于 http 4xx 错误:

const expectedError =
      error.response &&
      error.response.status >= 400 &&
      error.response.status < 500
// expectedError === true

而且这个区块不会被评估

if (!expectedError){
    console.log('Logging the error:', error)
    toast.error('خطایی رخ داده است')

    return Promise.reject(error)        
}

由于您没有else 块并且没有默认返回值,因此拦截器返回undefined(JS 中的默认返回值),它在try 块中处理,因为它不是错误

所以错误不是来自catch 块:

const result = await createPost(JSON.parse(JSON.stringify(this.state)))
// result is undefined
if (result.status === 200) // <-- error is from this line

因此,您可以简单地使用else 块或默认retrun,例如:

if (!expectedError){
    ...
    return Promise.reject(error)        
} else {
    return error // or Promise.resolve(error)
}

// OR

if (!expectedError){
    ...
    return Promise.reject(error)        
}

return error //etc

【讨论】:

    猜你喜欢
    • 2018-06-14
    • 2014-05-21
    • 1970-01-01
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2017-07-12
    • 2016-12-21
    相关资源
    最近更新 更多