Express Node.js + React Router无法进行API调用? "存取控制功能来源"

时间:2017-01-23 06:46:07

标签: node.js reactjs express react-router

这是我的第一个React.js应用程序,我正在尝试对非auth api进行简单的api调用。我正在Heroku(Framework: React.js (create-react-app))及其运行的Express Node.js中部署应用程序并使用React Router。 我的问题是,点击一个简单的按钮(调用handleClick())我想做一个API GET请求,但我经常通过控制台收到错误信息

  

无法加载Fetch API   https://rest-it-test.herokuapp.com/rest。没有   '访问控制允许来源'标题出现在请求的上   资源。起源' https://myherokuapp.herokuapp.com'是   因此不允许访问。响应具有HTTP状态代码400。   如果不透明响应满足您的需求,请将请求的模式设置为   '无CORS'在禁用CORS的情况下获取资源。

的src /部件/应用

import React, { PropTypes, Component } from 'react';
import classnames from 'classnames';

import logo from './logo.svg';
import './style.css';

var Twitter = require('twitter');
var request = require('request');

var client = new Twitter({
  consumer_key: process.env.TWITTER_CONSUMER,
  consumer_secret: process.env.TWITTER_SECRET
});



class App extends Component {
  // static propTypes = {}
  // static defaultProps = {}
  // state = {}
  constructor(props)
  {
    super(props)
    this.state = {
      input: ""
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  getInitialState(){
    return { input: '' };
  }

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

  handleClick(){
    console.log(this.state.input);
    request('https://rest-it-test.herokuapp.com/rest', function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body) // Print the google web page.
         }
    });

  }

  render() {
    const { className, ...props } = this.props;
    return (
      <div className={classnames('App', className)} {...props}>
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          <code>src/App.js</code> and save to reload.
        </p>
        <p>
          Testing HTML!!!
        </p>
        <input type="text" onChange={ this.handleChange } />
        <input
          type="button"
          value="Search"
          onClick={this.handleClick}
        />
      </div>
    );
  }
}

export default App;

服务器/ app.js

const express = require('express');
const morgan = require('morgan');
const path = require('path');
var cors = require('cors');

const app = express();

app.use(cors());

// Setup logger
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms'));

// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')));

// Use for React Router... Will always return main.
app.get('*', (req, res) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
  res.sendFile(path.resolve(__dirname, '..', 'build', 'index.html'));
});


module.exports = app;

以下列出了我尝试过的解决方案:

  1. 使用不同的库,例如restler。
  2. 尝试传递标题Access-Control-Allow-Origin&#34;,&#34; *&#34;,Access-Control-Allow-Headers&#34;,&#34; Origin,X-Requested-With, Content-Type,Accept&#34; ..等请求调用本身。
  3. 我无法想到其他解决方案,如果有人解决了这个问题,请告诉我。

    谢谢!

1 个答案:

答案 0 :(得分:0)

你遇到了几个不同的问题。

首先,CORS。除非客户端请求和远程服务器响应都包含克服此问题所必需的标头,否则浏览器基本上是相对于域的沙箱。您引用的错误消息告诉您响应被阻止,因为响应不包含任何“Access-Control-Allow-Origin”标头。这不是您可以通过在Express服务器上设置标头来解决的问题;这是Twitter的API必须设置的东西。据我所知,Twitter不允许这样做,所以这是一个死胡同。

其次,查看该状态代码。如果您可以通过CORS问题,您将收到的回复是:

signal.freqz()

为了访问API,您将不得不从服务器发出请求(不会出现CORS问题)并通过oauth流程进行身份验证。