简体   繁体   中英

CORS error when post request is send, but not get request in Spring Boot and Reactjs

I am learning spring boot and react right now.

And I run into a problem of CROS. After spending some time researching about this issue, what i understand is that when malicious access tries to get information stored in cache, it would prevent the access. Now, my web application consider my api request as malicious access.

So I added @CrossOrigin annotation in BookResourceImp.java. In the tutorial I watch, after adding @CrossOrign in the file, everything works fine.

However, when i send post request to application, i get a CROS error. although my get request works fine.

Some solution introduce response.setHeader in java file as here Spring Boot and CORS but since the guy in the tutorial was adding only CrossOrigin annotation, I would like to know why mine does not work although get request works.and if the solution from above link is the best option, please let me know.

Thank you so much in advance.

Book.js

import React from 'react';

import {Card, Form, Button, Col} from 'react-bootstrap';

import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faSave, faPlusSquare} from '@fortawesome/free-solid-svg-icons'

import axios from 'axios';

export default class Book extends React.Component {

    constructor(props) {
        super(props);

        this.state = this.initialState;
    }

    initialState = {
        title: '',
        author: '',
        url: '',
        isbn: '',
        price: '',
        lang: '',
    }

    submitBook = e => {
        alert(`${this.state.title}\n ${this.state.author}\n ${this.state.url}\n ${this.state.isbn}\n ${this.state.price}\n ${this.state.lang}\n ${this.state.title}`);
        e.preventDefault();

        const book = {
            title: this.state.title,
            author: this.state.author,
            url: this.state.url,
            isbn: this.state.isbn,
            price: this.state.price,
            lang: this.state.lang
        }

        axios.post("http://localhost:8081/rest/books", book)
            .then(res => {
                console.log("RES", res);
                if (res.data != null) {
                    this.setState(this.initialState);
                    alert("Book saved successfully")
                }
            })
            .catch(err => console.log(err))
    }

    bookChange = e => {
        this.setState({
            [e.target.name]: e.target.value
        });
    }


    render() {

        const {title, author, url, isbn, price, lang} = this.state;

        return (
            <Card className={"border border-dark bg-dark text-white"}>
                <Card.Header><FontAwesomeIcon icon={faSave} className="mr-2"/>Add Book</Card.Header>

                <Form id="bookFromId" onSubmit={this.submitBook}>
                    <Card.Body>
                        <Form.Row>
                            <Form.Group controlId="FormGridTitle" as={Col}>
                                <Form.Label>Title</Form.Label>
                                <Form.Control
                                    type="title"
                                    value={title}
                                    placeholder="Book Titile"
                                    className={"bg-dark text-white"}
                                    name='title'
                                    required
                                    onChange={this.bookChange}
                                />
                            </Form.Group>

                            <Form.Group controlId="formBasicEmail" as={Col}>
                                <Form.Label>Author</Form.Label>
                                <Form.Control
                                    type="text"
                                    value={author}
                                    placeholder="Author"
                                    className={"bg-dark text-white"}
                                    name='author'
                                    onChange={this.bookChange}
                                    required
                                />
                            </Form.Group>
                        </Form.Row>

                        <Form.Row>
                            <Form.Group controlId="formBasicEmail" as={Col}>
                                <Form.Label>Cover Photo URL</Form.Label>
                                <Form.Control
                                    type="text"
                                    value={url}
                                    placeholder="Book Titile"
                                    className={"bg-dark text-white"}
                                    name='url'
                                    onChange={this.bookChange}
                                    required
                                />
                            </Form.Group>

                            <Form.Group controlId="formBasicEmail" as={Col}>
                                <Form.Label>ISBN Number</Form.Label>
                                <Form.Control
                                    type="text"
                                    value={isbn}
                                    placeholder="Author"
                                    className={"bg-dark text-white"}
                                    name='isbn'
                                    onChange={this.bookChange}
                                    required
                                />
                            </Form.Group>
                        </Form.Row>

                        <Form.Row>
                            <Form.Group controlId="formBasicEmail" as={Col}>
                                <Form.Label>Price</Form.Label>
                                <Form.Control
                                    type="text"
                                    value={price}
                                    placeholder="Book Titile"
                                    className={"bg-dark text-white"}
                                    name='price'
                                    onChange={this.bookChange}
                                    required
                                />
                            </Form.Group>

                            <Form.Group controlId="formBasicEmail" as={Col}>
                                <Form.Label>Language</Form.Label>
                                <Form.Control
                                    type="text"
                                    value={lang}
                                    placeholder="Author"
                                    className={"bg-dark text-white"}
                                    name='lang'
                                    onChange={this.bookChange}
                                    required
                                />
                            </Form.Group>
                        </Form.Row>

                    </Card.Body>
                    <Card.Footer style={{"textAlign": "right"}}>
                        <Button size="sm" variant="success" type="submit">
                            <FontAwesomeIcon icon={faPlusSquare} className="mr-2"/>Submit
                        </Button>
                    </Card.Footer>
                </Form>
            </Card>
        );
    }
};

BookResourceImp.java

package com.mightyjava.resource.impl;

import java.util.Collection;
import java.util.Optional;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import com.mightyjava.domain.Book;
import com.mightyjava.exception.ApplicationException;
import com.mightyjava.exception.BookNotFoundException;
import com.mightyjava.resource.Resource;
import com.mightyjava.service.IService;

@RestController
@RequestMapping("/books")
@CrossOrigin(origins="http://localhost:3000")
public class BookResourceImpl implements Resource<Book> {
    
    private static Logger log = LoggerFactory.getLogger(BookResourceImpl.class);
    
    @Autowired
    private IService<Book> bookService;

    @Override
    public ResponseEntity<Collection<Book>> findAll() {
        log.info("BookResourceImpl - findAll");

Your @RequestMapping("/books") appears to only allow /books whereas your post request is to: "http://localhost:8081/rest/books".

Adding this webconfigurer will enable cors for the whole application:

package com.codurance.marsroverapi.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig {

  @Configuration
  public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
      registry.addMapping("/**");
    }
  }
}

Add this on your class path everything will be ok

    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class MyCorsFilterConfig implements Filter {

        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            final HttpServletResponse response = (HttpServletResponse) res;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, enctype");
            response.setHeader("Access-Control-Max-Age", "3600");
            if (HttpMethod.OPTIONS.name().equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
            } else {
                chain.doFilter(req, res);
            }
        }

        @Override
        public void destroy() {
        }

        @Override
        public void init(FilterConfig config) throws ServletException {
        }


    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM