1

我正在使用 React 和 Express.js 为 Google Vision API 创建文件上传服务。我已经创建了一个简单的文件上传到该帖子以在提交时“/上传”。上传后,我一直遇到这个错误:

Proxy error: Could not proxy request /upload from localhost:3000 to http://localhost:3000/ (ECONNRESET).

这是构成简单图像上传表单的我的 react app.js。

应用程序.js

import React, { Component } from 'react';
import {
  Button,
  Col,
  Form,
  FormGroup,
  Label,
  Input,
  FormText
} from 'reactstrap';
import './App.css';

class App extends Component {

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src='https://media1.tenor.com/images/aa12acad78c918bb62fa41cf7af8cf75/tenor.gif?itemid=5087595' className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to Readr</h1>
        </header>
        <Form action='/upload' method="POST">
          <FormGroup row>
            <Label for="exampleFile" sm={2}>File</Label>
            <Col sm={10}>
              <Input type='file' name='image' />
              <FormText color="muted">
              </FormText>
            </Col>
          </FormGroup>
          <FormGroup row>
            <Label for="exampleSelect" sm={2}>What are we trying to see today in the image?</Label>
            <Col sm={10}>
              <Input type="select" name="select" id="exampleSelect">
                <option>Labels</option>
                <option>Faces</option>
                <option>Landmarks</option>
                <option>Text</option>
                <option>Logos</option>
              </Input>
            </Col>
          </FormGroup>
          <FormGroup check row>
            <Col sm={{ size: 10, offset: 2 }}>
              <Button type="submit">Submit</Button>
            </Col>
          </FormGroup>
        </Form>
      </div>
    );
  }
}

export default App;

服务器.js

'use strict';
// Middleware
const express = require('express');
const fs = require('fs');
const util = require('util');
const mime = require('mime-types');
const multer = require('multer');
const upload = multer({ dest: 'uploads/',
 rename: function (fieldname, filename) {
   return filename;
 },
});
const Image = require('./data/db.js');
const path = require('path');

// Imports the Google Cloud client library
const vision = require('@google-cloud/vision');
// Creates a client
const client = new vision.ImageAnnotatorClient();

let app = express();

// Simple upload form

app.get('/', function(req, res) {
  res.sendFile(path.join(__dirname + '/client/index.html'));
});

// Get the uploaded image
// Image is uploaded to req.file.path
app.post('/upload', upload.single('image'), function(req, res, next) {

  // Choose what the Vision API should detect
  // Choices are: faces, landmarks, labels, logos, properties, safeSearch, texts
  var types = ['labels'];

  // Send the image to the Cloud Vision API
  client
  .labelDetection(req.file.path)
  .then(results => {
    // Pull all labels from POST request
    const labels = [];
    results[0].labelAnnotations.forEach(function(element) {
      labels.push(element.description);
    })
    res.writeHead(200, {
      'Content-Type': 'text/html'
    });

    // Create new Image Record
    let image = new Image ({});
    image.data = fs.readFileSync(req.file.path);
    image.contentType = 'image/png';
    image.labels = labels;
    image.save((err) => {
      if (err) {
        console.log('Error:' , err);
      }
    })

    res.write('<!DOCTYPE HTML><html><body>');

    // Base64 the image so we can display it on the page
    res.write('<img width=600 src="' + base64Image(req.file.path) + '"><br>');

    // Write out the JSON output of the Vision API
    res.write(JSON.stringify(labels, null, 4));
    // Delete file (optional)
    fs.unlinkSync(req.file.path);

    res.end('</body></html>');
  })

  // ERROR from Cloud Vision API
  .catch(err => {
    console.log(err);
    res.end('Cloud Vision Error:' , err);
  });
});

app.listen(8080);
console.log('Server listening on 8080');

// Turn into Base64, an easy encoding for small images
function base64Image(src) {
  var data = fs.readFileSync(src).toString('base64');
  return util.format('data:%s;base64,%s', mime.lookup(src), data);
}

包.json

   {
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "bootstrap": "^4.0.0",
    "react": "^16.3.0",
    "react-dom": "^16.3.0",
    "react-scripts": "1.1.1",
    "reactstrap": "^5.0.0-beta.3",
    "@google-cloud/vision": "^0.18.0",
    "babel": "^6.23.0",
    "express": "^4.13.4",
    "mime": "^1.3.4",
    "mime-lookup": "0.0.2",
    "mime-types": "^2.1.18",
    "mongodb": "^3.0.5",
    "mongoose": "^5.0.12",
    "multer": "^1.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "server": "GOOGLE_APPLICATION_CREDENTIALS='key.json' nodemon ./public/sample.js --ignore client",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:3000/"
}

我是使用代理进行 react 和 express.js 应用程序的新手。有人可以帮助澄清导致此代理错误的确切原因吗?

4

1 回答 1

1

据我了解,您必须针对运行快速服务器的端口。在这种情况下,端口是 8080。我还假设您使用 create-react-app 来构建客户端,因为包内提供了代理。

"proxy": {
"/upload": {
  "target": "http://localhost:8080"
},

也许您已经知道,但是如果您想代理嵌套在 /upload 路由中的其他请求,您可以使用 /upload/* 代理嵌套路由,而无需在代理配置中创建单独的路由。

您可以随时查看文档以了解有关如何在此处设置代理配置的更多信息: facebook/create-react-app

在代理部分,他们有详细的说明。

希望有帮助。

于 2018-05-29T12:34:16.860 回答