Heroku:POST错误414(Request-URI太长)

时间:2017-05-24 10:19:34

标签: javascript node.js angular heroku

渴望行为:

Post请求有效,轮询保存在数据库中。

状况:

我的SPA在我的本地计算机上正常运行。但是当我上传到Heroku时,当我尝试创建一个民意调查时,它会给我一个414错误。

导致此问题的原因以及如何解决?

以下是用于创建投票的POST代码。它通过请求标头传递用户令牌,以便我可以在后端检索它以授权创建轮询。我现在唯一的问题是我收到错误400:/

CODE:

客户端

addPoll(poll: Poll) {
    const body = JSON.stringify(poll);
    const token = localStorage.getItem('token')
        ? '?token=' + localStorage.getItem('token')
        : '';
    const options = new RequestOptions();
    if (!options.headers) {
        options.headers = new Headers({
          'Content-Type': 'application/json',
          'Authorization': 'Bearer '+token
        });
    }
    return this.http.post('http://localhost:3000/poll', body,  options)
        .map((response: Response) => {
            const result = response.json();
            const poll = new Poll(
                result.obj.title,
                result.obj.choice1,
                result.obj.choice2,
                0,
                0,
                result.obj.user.firstName,
                result.obj._id,
                result.obj.user._id,
                );
            this.polls.unshift(poll);
            return poll;
        })
        .catch((error: Response) => {
            this.errorService.handleError(error.json());
            return Observable.throw(error);
        });
}

服务器

function getToken (req) {
    if (req.options.headers.authorization && req.options.headers.authorization.split(' ')[0] === 'Bearer') {
        console.log("WE ARE IN!");
        return req.options.headers.authorization.split(' ')[1];
    }
    return null;
  }

router.post('/', function (req, res, next) {
    console.log("token: "+getToken(req));
    var decoded = jwt.decode(getToken(req));
    User.findById(decoded.user._id, function (err, user) {
        if (err) {
            return res.status(500).json({
                title: 'An error occurred',
                error: err
            });
        }
        var poll = new Poll({
            title: req.body.title,
            choice1: req.body.choice1,
            choice2: req.body.choice2,
            counter1: 0,
            counter2: 0,
            user: user
        });

        poll.save(function (err, result) {
            if (err) {
                return res.status(500).json({
                    title: 'An error occurred',
                    error: err
                });
            }
            user.polls.push(result);
            user.save();
            res.status(201).json({
                poll: 'Saved poll',
                obj: result
            });
        });
    });
});

错误:

enter image description here

3 个答案:

答案 0 :(得分:2)

我检查了您的代码并测试了network calls,您有两个问题

1)注册时,您不允许lastName转到服务器,因此无法signUp

所以,参数应该是,

{
    "email": "test@mailinator.com",
    "firstName": "test",
    "lastName": "test",
    "password": "12345678",
    "votes": "test"
}

2)令牌,应通过标头而不是查询参数传递。

您有错误,

<强> const token = localStorage.getItem('token') ? '?token=' + localStorage.getItem('token') : '';

应该是

<强> const token = localStorage.getItem('token') ? localStorage.getItem('token') : '';

addPoll(poll: Poll) {
    const body = JSON.stringify(poll);
    const token = localStorage.getItem('token')
        ? localStorage.getItem('token')
        : '';
    const options = new RequestOptions();
    if (!options.headers) {
        options.headers = new Headers({
          'Content-Type': 'application/json',
          'Authorization': 'Bearer '+token
        });
    }
    return this.http.post('http://localhost:3000/poll', body,  options)
        .map((response: Response) => {
            const result = response.json();
            const poll = new Poll(
                result.obj.title,
                result.obj.choice1,
                result.obj.choice2,
                0,
                0,
                result.obj.user.firstName,
                result.obj._id,
                result.obj.user._id,
                );
            this.polls.unshift(poll);
            return poll;
        })
        .catch((error: Response) => {
            this.errorService.handleError(error.json());
            return Observable.throw(error);
        });
}

答案 1 :(得分:1)

正如@trichetriche建议你应该将令牌放入标题而不是URL:

addPoll(poll: Poll) {
    const body = JSON.stringify(poll);
    const token = localStorage.getItem('token');
    const headers = new Headers({
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + token
        });
    return this.http.post('http://localhost:3000/poll', body, {headers: headers})
        .map((response: Response) => {
            const result = response.json();
            const poll = new Poll(
                result.obj.title,
                result.obj.choice1,
                result.obj.choice2,
                0,
                0,
                result.obj.user.firstName,
                result.obj._id,
                result.obj.user._id,
                );
            this.polls.unshift(poll);
            return poll;
        })
        .catch((error: Response) => {
            this.errorService.handleError(error.json());
            return Observable.throw(error);
        });
}

当然,您还需要更改服务器代码,并从标头而不是查询参数中删除令牌。

据我所知'express-jwt'默认使用此header参数,但您可以手动解析它:

function getToken (req) {
    if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
        return req.headers.authorization.split(' ')[1];
    }
    return null;
  }

答案 2 :(得分:1)

  1. 您的网络请求格式错误授权令牌或者您可能无法将其正确存储在本地存储中。
  2. 传递poll对象而不是body(这是stringifyed,不需要stringify,它需要是有效的Json对象)
  3. 使用RequestOptions ..

        if (!options.headers)
            options.headers = new Headers();
    
        options.headers.append('Content-Type', 'application/json'); //you may not need this though.
        options.headers.append('Authorization', 'Bearer '+ token);
    
        return this.http.post('https://voting-app-10.herokuapp.com/poll', poll, options)
    
        ....
        ....