【问题标题】:Express api does not recieve data keys, even though they have been specified and sent in the react frontendExpress api 不接收数据键,即使它们已在反应前端指定并发送
【发布时间】:2018-01-20 14:42:14
【问题描述】:

我正在尝试使用托管在单独应用程序中的 react 将数据发送到 rest api,即使我在 Chrome 中记录了结果并得到了这个,api 也没有收到发送的密钥:(2) ["imageSrc", File]0: "imageSrc"1: File {name: "22196156_10154999506505959_5971486080451335945_n.jpg", lastModified: 1507302065124, lastModifiedDate: Fri Oct 06 2017 16:01:05 GMT+0100 (WAT), webkitRelativePath: "", size: 32766, …}length: 2__proto__: Array(0)

这是我的 api 后控制器

module.exports.createImage = function(req, res, next){
  Image.
    create({
      imageSrc: req.body.image,
      post: req.body.post
    }, function(err, image){
      if(err){
        return next(err)
      }
      res.status(201).json(image);
    });
}

这是我的反应表单页面:

handleSubmit(e){
    e.preventDefault();
    if(!this.uploadFile){
      return;
    }
    let data = new FormData();
    data.append('imageSrc', this.uploadFile);
    data.append('post', this.state.value);
    console.log(...data);

    fetch('http://127.0.0.1:4400/api/images', {
      method: 'POST',
      body: data
    }).then((res) => {
      this.setState({
        status: 'uploading',
        statusMsg: (<p>Uploading...</p>)
      });
      console.log(res)
      return res.json();
    }).then((val) => {
      if(val.message == 'ok'){
        this.setState({
          status: 'done',
          statusMsg: (<p id='checkMark'><i className="fa fa-check"></i></p>)
        });
        console.log(val)

        timer = _.delay(this.setOriginalText, 1000);
      }
    }).catch(error =>{
      return error;
    });
  }

  handleTextChange(e){
    this.setState({value: e.target.value});
  }

  handleImageChange(e){
    e.preventDefault();
    let reader = new FileReader();
    let file = e.target.files[0];

    reader.onloadend = () => {
      this.setState({
        imagePreviewUrl: reader.result,
        style: {background: ''}
      });
      this.uploadFile = file;
    };
    
    reader.readAsDataURL(file);
  }
  
  render(){
    let{imagePreviewUrl} = this.state;
    let imagePreview = this.state.statusMsg;
    if(imagePreviewUrl){
      imagePreview = (<img src={imagePreviewUrl} className="dropPreview" />);
    }
    return(
      <div className="container">
      <form>
        <div
          onDragOver={this.onDragOver}
          onDragLeave={this.onDragLeave}
          className="dropZoneContainer">

          <div className="dropZone" id="upload-file-container" style={this.state.style}>{imagePreview}
            <input type="file" name="imageSrc" onChange={this.handleImageChange} />
          </div>

          <label htmlFor="post">Post:</label> 
            
            <textarea value={this.state.value} name="post" placeholder="Write something related to the picture" onChange={this.handleTextChange} />
                   
        </div>
        <a href="" onClick={this.handleSubmit} className="icon-button cloudicon">
            <i className="fa fa-cloud-upload"></i><span>Post</span>
        </a>
      </form>
      </div>
    );
  }
}

我不知道我可能做错了什么,如果有任何帮助,我将不胜感激。

编辑:类构造函数。

class PostUpload extends React.Component{

  constructor(props){
    super(props);
    this.state = {
      imagePreviewUrl: '',
      status: 'idle',
      statusMsg: (<p>Click or drop files here to upload</p>),
      style: {},
      value: ''
    };

    this.uploadFile = '';
    this.handleTextChange = this.handleTextChange.bind(this);
    this.handleImageChange = this.handleImageChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.onDragOver = this.onDragOver.bind(this);
    this.onDragLeave = this.onDragLeave.bind(this);
    this.setOriginalText = this.setOriginalText.bind(this);
  }

【问题讨论】:

  • 您是否检查过是否有任何请求到达/api/images 端点?您是否绑定了您正在触发的方法以上传和提交图像?
  • 我查过了。请求确实到达了,但请求正文要么为空,要么奇怪地不包含预期的键。控制台产生此错误消息:POST /api/images 500 21.194 ms - 1039 ValidationError: image validation failed: imageSrc: Path imageSrc is required., post: Path post is required。
  • 关于你的第二个问题,我不确定我是否理解你。
  • 然后,请将您的类构造函数添加到代码中。
  • 完成。请检查编辑。

标签: javascript node.js reactjs express


【解决方案1】:

您需要使用库来解析您使用fetch 发送到 Express 的表单。例如,我使用了multiparty(因此您不需要在fetch 请求中设置任何带有Content-Type 的标头)。

const fs = require('fs');
const express = require('express');
const bodyParser = require('body-parser');
const multiparty = require('multiparty');

const app = express();
const port = 4400;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

...

app.post('/api/images', function(req, res, next) {
  const form = new multiparty.Form();
  form.parse(req, (err, fields, files) => {
    if (err) {
      return next(err);
    }
    // console.log(fields); /* fields, where you will find the { post } info. */
    // console.log(files); /* files, where you will find the file uploaded. */
    try {
      const imgPath = files.imageSrc[0].path;
      const img = fs.readFileSync(imgPath);
      res.writeHead(200, { 'Content-Type': files.imageSrc[0].headers['content-type'] });
      res.end(img, 'binary');
    } catch(Error) {
      res.status(400).send('Error when creating image');
    }
  });
  return;
});

我在这个 Github repository 上上传了一个工作项目以及我向您提出的实施解决方案,因此您可以根据需要检查代码。

【讨论】:

    猜你喜欢
    • 2019-12-24
    • 2020-02-09
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 2014-05-09
    • 2022-01-28
    相关资源
    最近更新 更多