如何从浏览器向Node.js服务器发送大文件?

时间:2017-03-25 20:25:29

标签: javascript node.js cors fetch-api

我正在尝试使用data: URL从客户端向服务器发送图像。我读取上传图像并将数据发送到服务器的功能非常简单:

getTags = event => {
    const file = event.target.files[0];

    if (!file.type.match('image.*')) {
      return;
    }

    const reader = new FileReader();

    reader.onload = (theFile => {
      return (e) => {
        this.sendDataToServer(e.target.result, theFile.type);
      };
    })(file);

    reader.readAsDataURL(file);
  }

sendDataToServer = (data, fileType) => {
    const options = {
      method: 'POST',
      headers: {
        'Content-Type': fileType,
      },
      body: JSON.stringify({data}),
      cache: 'default'
    }
    fetch('http://localhost:5000/img', options)
    .then(res =>  res.text())
    .then(body => {
        console.log(body);
    });
  }

如果我在e.target.result之前打印sendDataToServer,我会看到有效的data: URL

所以,我的服务器:

const app = express();
app.use(cors());
app.use(helmet());
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.post('/img', (req, res, next) => {
  const data = decodeURIComponent(req.body.data);
  console.log(data);
  // ... 

但是在网络标签的Chrome DevTools中,我看到了:

Request URL:http://localhost:5000/img
Request Method:OPTIONS
Status Code:204 No Content
Remote Address:52.15.183.149:80
Response Headers
view source
Access-Control-Allow-Headers:content-type
Access-Control-Allow-Methods:GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin:*
Date:Sat, 25 Mar 2017 20:18:09 GMT
X-Powered-By:Express
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:b580f823.ngrok.io
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.1165

在服务器上,console.log只打印undefined。无法理解为什么会发生这种情况。我的错误在哪里?

1 个答案:

答案 0 :(得分:2)

显示客户端信息的问题中的所有内容都表明它在客户端正常工作。

所以似乎服务器端必定存在一些问题而不是由任何客户端错误引起的。

我这样说是因为:

  1. 请求的devtools代码段显示Request Method:OPTIONSwhich is expected,因为POST的{​​{1}}标题不是Content-Typeapplication/x-www-form-urlencoded, 或multipart/form-data

  2. 在这种情况下,您的浏览器会首先发送一个CORS预检text/plain请求,并希望获得一个OPTIONS响应标头以及一个Access-Control-Allow-Headers:content-type,包括Access-Control-Allow-Methods ,和POST

  3. 问题中的devtools代码段显示它按预期获得所有内容,因此它应该发送实际的Access-Control-Allow-Origin。您没有为POST显示devtools代码段,但如果您的浏览器没有执行实际的POST,则会将某种错误记录到devtools控制台。

  4. 因此,除非我遗漏了某些内容,否则客户端代码中不会出现错误,因此服务器端的某些问题必然会导致其失败。