ReactJS не может отправить запрос POST из-за предварительной проверки параметров CORS

Всякий раз, когда я отправляю запрос POST на сервер, OPTIONS возвращает ВСЕГДА.

У меня очень простое приложение для входа в систему с использованием React и Apollo. Когда я отправляю форму, mutation должен быть отправлен на сервер с использованием запроса ПОЧТА, но ПАРАМЕТРЫ всегда перехватывает.

Как вы можете видеть здесь (используя хром): ReactJS не может отправить запрос POST из-за предварительной проверки параметров CORS

Но когда я использую Fire Fox, после OPTIONS запрашивается ПОЧТА, как вы можете видеть здесь:

ReactJS не может отправить запрос POST из-за предварительной проверки параметров CORS

Я знаю, что не могу отключить ОПЦИИ предполетной проверки, потому что, как я выяснил, использование Content-Type: application/json / bodyParser.json() запускает предполетную проверку.

Но мне нужен Content-Type: application/json, чтобы graphql работал. Но есть ли способ просто ПОЧТА запрос и игнорировать ПАРАМЕТРЫ? Мне нужен this.props.data, возвращенный запросом POST ReactJS не может отправить запрос POST из-за предварительной проверки параметров CORS

поэтому я могу сохранить токен в localStorage в клиентском браузере ...

Мои проблемы были:

  • Запрос POST никогда не выполняется из-за OPTIONS (хром)
  • Я не могу получить доступ к this.props.data в компоненте React, потому что OPTIONS всегда возвращает ПЕРВЫЙ перед фактическим ПОЧТА (в Firefox)

Я просто хочу получить data из запроса POST ?

Это проблема с корсами? Может ли кто-нибудь просветить меня, что я делаю не так? Большое спасибо заранее.

PS: Я пробовал эту ссылку: https://github.com/graphql/express-graphql/issues/14, но все же не могу исправить эту проблему ...

Вот мой сервер:

const express = require('express')
const morgan = require('morgan')
const bodyParser = require('body-parser')
// Grahql
const expressGraphQL = require('express-graphql')
const jwt = require('jsonwebtoken')
const cors = require('cors')
const chalk = require('chalk')

const model = require('./db/models')
const schema = require('./schema/schema')

const app = express()
app.use(cors())
app.options('*', cors())
app.use(bodyParser.json())
app.use(morgan('dev'))

// secret key
const SECRET = 'eggieandsausage'

// this method checks token authenticity from
// user attempting to login
const verifyTokenAuthenticity = async (req, res, next) => {
    const token = req.headers['authentication']
    try {
        // verify token from headers
        const { user } = await jwt.verify(token, SECRET)
        // store user in req
        req.user = user
    } catch(err) {
        console.info(err)
    }
    // proceed
    next()
}

// Graphql
//app.use(verifyTokenAuthenticity)

app.use('/graphql', expressGraphQL(req => ({
    schema,
    graphiql: true,
    // this context is accessible within resolve()
    context: {
        model,
        SECRET,
        user: req.user
    }
})))


// Initial Route
app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html')
})

const PORT = process.env.PORT || 8080
app.listen(PORT, () => console.info(chalk.green(`MAGIC STARTS AT PORT ${PORT}`)))

Вот моя мутация:

const graphql = require('graphql')
const {
    GraphQLObjectType,
    GraphQLString,
    GraphQLNonNull
} = graphql
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')



const UserType = require('./types/user_type')

const mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        signup: {
            type: UserType,
            args: { 
                email: { type: new GraphQLNonNull(GraphQLString) },
                password: { type: new GraphQLNonNull(GraphQLString) }
            },
            resolve(parentValue, { email, password }, { model }) {
                return new Promise((resolve, reject) => {
                    model.User.create({
                        email,
                        password
                    })
                    .then(user => {
                        if (!user)
                            return reject('Sorry. something went wrong')
                        resolve(user)
                    })
                    .catch(error => reject(error))
                })
            }
        },
        signin: {
            type: UserType,
            args: {
                email: { type: new GraphQLNonNull(GraphQLString) },
                password: { type: new GraphQLNonNull(GraphQLString) }
            },
            // params: parentValue, args, context
            resolve(parentValue, { email, password }, { model, SECRET }) {
                return new Promise((resolve, reject) => {
                    model.User.find({ where: { email } })
                        .then(user => {
                            if (!user)
                                return reject('Invalid Credentials')
                            if (!bcrypt.compareSync(password, user.password))
                                return reject('Invalid Credentials')

                            const token = jwt.sign({ user: { id: user.id, email: user.email } }, SECRET, { expiresIn: '1yr' })
                            user.token = token  // add token property to user object which will be resolved

                            resolve(user)

                        })
                        .catch(error => reject(error))
                })

            }
        }
    }
})

module.exports = mutation

И это страница входа в систему

import React from 'react'
import gql from 'graphql-tag'
import { graphql } from 'react-apollo'
class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = { email: '[email protected]', password: 'password' }
    }
    onSubmit(e) {
        e.preventDefault()
        const { email, password } = this.state
        console.info({ email, password })
        this.props.mutate({
            variables: { email, password }
        }).then(() => console.info(this.props.data))
        .catch(() => console.info("error"))
    }
    render() {
        return (
            <form onSubmit = {this.onSubmit.bind(this)}>
                <label>Email</label>
                <input type = "text" onChange = {(e) => this.setState({ email: e.target.value})} value = {this.state.email} />
                <br/>
                <label>Password</label>
                <input type = "password" onChange = {(e) => this.setState({ password: e.target.value})} value = {this.state.password} />
                <button type = "submit" >Login</button>
            </form>
        )
    }
}
const mutation = gql`
    mutation SignIn($email: String!, $password: String!){
      signin(email: $email, password: $password) {
        token
      }
    }
`;
export default graphql(mutation)(App)

Мой провайдер:

import React from 'react'
import ReactDOM from 'react-dom'

import ApolloClient, { createNetworkInterface } from 'apollo-client'
import { ApolloProvider } from 'react-apollo'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import App from './App'
import Header from './components/Header'
import Profile from './components/Profile'
const networkInterface = createNetworkInterface({
  uri: 'http://localhost:8080/graphql'
});
const client = new ApolloClient({
    networkInterface,
    dataIdFromObject: o => o.id
})
const Root = () => {
  return (
    <ApolloProvider client = {client}>
      <Router>
          <Switch>
          <Route exact path = "/" component = {App} />
          <Route path = "/profile" component = {Profile} />
        </Switch>
      </Router>
    </ApolloProvider>
  )
}
ReactDOM.render(<Root />, document.getElementById('root'));

каков URL-адрес вашего пользовательского интерфейса?

Hriday Modi 22.06.2018 17:56

@Hriday Это локальный: 3000

Welp 22.06.2018 17:57

Если вы используете приложение create-response-app, вы можете проксировать свой запрос. например "proxy": { "/graphql": { "target": "http://localhost:8080" } }

Hriday Modi 22.06.2018 18:01

Могу я узнать, где его поставить? Да я использую cra

Welp 22.06.2018 18:02

В package.json, самый внешний уровень, то есть в основном объекте

Hriday Modi 22.06.2018 18:04

Я попробую я сэр

Welp 22.06.2018 18:07

Он все еще не работает, сэр

Welp 22.06.2018 18:08

Для справки https://medium.freecodecamp.org/how-to-make-create-react-app‌ -work-with-a-node-ba‌ ckend-api-7c5c48acb1‌ b0. Этот блог предназначен для node js, но должен работать для всех backend API.

Hriday Modi 22.06.2018 18:09

Позвольте нам продолжить обсуждение в чате.

Hriday Modi 22.06.2018 18:09

я что-то отправил в чат сэр

Welp 22.06.2018 18:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
10
979
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны использовать прокси в проекте create-react-app.

Добавьте следующий прокси в основной объект package.json:

"/graphql": {
  "target": "http://localhost:8080/",
  "changeOrigin": true
}

Это в основном ваш запрос от «http: // локальный: 3000 / graphql» к «http: // локальный: 8080 / graphql».

Также измените свой код, чтобы использовать относительный URL-адрес API. Итак, теперь это будет:

 uri: '/graphql'

Это вызовет api-адрес вашего локального URL-адреса, и сервер узла проксирует его на указанную цель. Следовательно, здесь нет перекрестного происхождения.

Другие вопросы по теме