CORS 标头“Access-Control-Allow-Origin”缺少 REACT
Posted
技术标签:
【中文标题】CORS 标头“Access-Control-Allow-Origin”缺少 REACT【英文标题】:CORS header ‘Access-Control-Allow-Origin’ missing REACT 【发布时间】:2021-07-15 01:54:54 【问题描述】:我正在 Spring Boot 之上构建一个 React 应用程序。当我尝试向 localhost:8080 发出 put 请求时,我的浏览器上出现了这些错误
跨域请求被阻止:同源策略不允许读取位于 http://localhost:8080/products 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。
跨域请求被阻止:同源策略不允许读取位于 http://localhost:8080/products 的远程资源。 (原因:CORS 请求没有成功)
我已经在我的服务器端为 localhost 3000 设置了@CrossOrigin。
一段时间以来一直试图通过添加标头、代理甚至在各处使用 Firefox CORS 来解决此问题。似乎没有任何效果。
请看下面我的前端代码
import React, Component from "react";
import Card, Form, Button from "react-bootstrap";
import axios from "axios";
import Toasting from "./Toasting";
export default class AddProducts extends Component
constructor(props)
super(props);
this.state = this.startState;
this.state.toast = false;
this.productChange = this.productChange.bind(this);
this.submitProduct = this.submitProduct.bind(this);
var config =
headers: 'Access-Control-Allow-Origin': '*'
;
startState = id: "", name: "", brand: "", made: "", price: "" ;
componentDidMount()
const productId = this.props.match.params.id;
if (productId)
this.findProductById(productId);
findProductById = (productId) =>
axios
.get("http://localhost:8080/products/" + productId)
.then((response) =>
if (response.data != null)
this.setState(
id: response.data.id,
name: response.data.name,
brand: response.data.brand,
made: response.data.madein,
price: response.data.price,
);
)
.catch((error) =>
console.error("Error has been caught: " + error);
console.log(error);
);
;
reset = () =>
this.setState(() => this.startState);
;
submitProduct = (event) =>
//Prevent default submit action
event.preventDefault();
const product =
id: this.state.id,
name: this.state.name,
brand: this.state.brand,
madein: this.state.made,
price: this.state.price,
;
axios.post("http://localhost:8080/products", product)
.then((response) =>
if (response.data != null)
this.setState( toast: true );
setTimeout(() => this.setState( toast: false ), 3000);
else
this.setState( toast: false );
);
this.setState(this.startState);
;
productChange = (event) =>
this.setState(
[event.target.name]: event.target.value,
);
;
productList = () =>
return this.props.history.push("/");
;
updateProduct = event =>
//Prevent default submit action
event.preventDefault();
const product =
id: this.state.id,
name: this.state.name,
brand: this.state.brand,
madein: this.state.made,
price: this.state.price,
;
***************THIS IS WHERE THE ERROR IS**********************************************
axios.put("http://localhost:8080/products", product, this.config).then((response) =>
if(response.data != null)
this.setState( toast: true );
setTimeout(() => this.setState( toast: false ), 3000);
setTimeout(() => this.productList(), 3000);
else
this.setState( toast: false );
);
this.setState(this.startState);
;
render()
const name, brand, made, price = this.state;
return (
<div>
<div style= display: this.state.toast ? "block" : "none" >
<Toasting
toast=this.state.toast
message="Product has been successfully saved!!!"
type="success"
/>
</div>
<Card className="border border-dark bg-dark text-white">
<Card.Header align="center">
" "
this.state.id ? "Update a Product" : "Add a Product"
</Card.Header>
<Form
onSubmit=this.state.id ? this.updateProduct : this.submitProduct
id="productFormId"
onReset=this.reset
>
<Card.Body>
<Form.Row>
<Form.Group controlId="formGridName">
<Form.Label>Product Name</Form.Label>
<Form.Control
required
autoComplete="off"
type="text"
name="name"
value=name
onChange=this.productChange
required
autoComplete="off"
className="bg-dark text-white"
placeholder="Enter Product Name"
/>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group controlId="formGridBrand">
<Form.Label>Brand</Form.Label>
<Form.Control
required
autoComplete="off"
type="text"
name="brand"
value=brand
onChange=this.productChange
className="bg-dark text-white"
placeholder="Enter Brand Name"
/>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group controlId="formGridMade">
<Form.Label>Made</Form.Label>
<Form.Control
required
autoComplete="off"
type="text"
name="made"
value=made
onChange=this.productChange
className="bg-dark text-white"
placeholder="Made in"
/>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group controlId="formGridPrice">
<Form.Label>Price</Form.Label>
<Form.Control
required
autoComplete="off"
type="text"
name="price"
value=price
onChange=this.productChange
className="bg-dark text-white"
placeholder="Product Price"
/>
</Form.Group>
</Form.Row>
</Card.Body>
<Card.Footer>
<Button size="sm" variant="success" type="submit">
this.state.id ? "Update" : "Submit"
</Button>" "
<Button size="sm" variant="info" type="reset">
Undo
</Button>" "
<Button
size="sm"
variant="info"
type="button"
onClick=this.productList.bind()
>
Products
</Button>
</Card.Footer>
</Form>
</Card>
</div>
);
请看下面我的产品控制器类服务器端
package ie.sw.spring;
import java.util.List;
import java.util.NoSuchElementException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.CrossOrigin;
@RestController
@CrossOrigin("http://localhost:3000")
public class ProductController
@Autowired
private ProductService service;
@GetMapping("/products")
public List<Product> list()
return service.listAll();
// Get products by their id
@GetMapping("/products/id")
public ResponseEntity<Product> get(@PathVariable Long id)
try
Product product = service.get(id);
return new ResponseEntity<Product>(product, HttpStatus.OK);
catch (NoSuchElementException e)
return new ResponseEntity<Product>(HttpStatus.NOT_FOUND);
// Handle post requests
@PostMapping("/products")
public void add(@RequestBody Product product)
service.save(product);
// Update a product
@PutMapping("/products/id")
public ResponseEntity<?> update(@RequestBody Product product, @PathVariable Long id)
try
Product existProduct = service.get(id);
service.save(product);
return new ResponseEntity<>(HttpStatus.OK);
catch (NoSuchElementException e)
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
@DeleteMapping("/products/id")
public void delete(@PathVariable Long id)
service.delete(id);
【问题讨论】:
您不应从前端附加 CORSheaders
。所以,删除它。之后,您需要确保 URL http://localhost:8080/products/SOME_ID_HERE"
在 postman 之类的工具中有效。只有在它适用于邮递员之后,您才应该调试 CORS 问题。那么,它对邮递员有效吗?
【参考方案1】:
***************THIS IS WHERE THE ERROR IS**********************************************
axios.put("http://localhost:8080/products", product, this.config).then((response) =>
...
@PutMapping("/products/id")
public ResponseEntity<?> update(@RequestBody Product product, @PathVariable Long id)
...
我认为您在使用axios.put
创建请求时错过了路径变量。您应该删除 @PathVariable Long id
或者您必须在请求中传递 id。
Option 1
axios.put("http://localhost:8080/products/" + productId, product, this.config).then((response) =>
...
@PutMapping("/products/id")
public ResponseEntity<?> update(@RequestBody Product product, @PathVariable Long id)
...
Option 2
axios.put("http://localhost:8080/products", product, this.config).then((response) =>
...
@PutMapping("/products")
public ResponseEntity<?> update(@RequestBody Product product)
...
另外,更改@CrossOrigin 如下
@CrossOrigin(origins = "http://localhost:3000", methods = RequestMethod.OPTIONS, RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, allowedHeaders = "*", allowCredentials = "true")
你可能也看过here
【讨论】:
【参考方案2】:您是否尝试将 "proxy": "http://localhost:8080"
添加到 package.json 文件中。这对我有帮助。我遇到了同样的问题。
【讨论】:
我确实什么都没做 您是否尝试过创建自定义服务器并设置代理? 不,我该怎么办? 你的后端是 NodeJS/Express.js 吗? 嗯,我没有使用 Spring 的经验,所以我无法帮助你,但你应该再次检查你的 Spring 配置。也许后端有东西阻塞。您也可以尝试将"Access-Control-Allow-Headers", "X-Requested-With"
添加到标题中。【参考方案3】:
@CrossOrigin("http://localhost:3000")
错了,试试
@CrossOrigin("http://localhost:8080")
【讨论】:
【参考方案4】:我已经在我的服务器端为 localhost 3000 设置了@CrossOrigin。
跨域请求被阻止:同源策略不允许读取 http://localhost:8080/products 上的远程资源。 (原因:CORS 缺少标头“Access-Control-Allow-Origin”)。
您的错误是针对localhost:8080
。
解决方案:
-
在你的服务器端设置
localhost:8080
。
你可以在你的服务器端设置*
,这是不推荐的,它
设置所有网址。
或者另一种解决方案是将前端应用程序中的端口更改为
一个你放在背后的。
【讨论】:
【参考方案5】:如果您只是尝试在本地运行,您是否尝试过 chrome 插件?
https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf
【讨论】:
【参考方案6】:我认为本地主机上的 cors 不起作用。
看看下面的页面。
Why does my http://localhost CORS origin not work?
https://medium.com/swlh/avoiding-cors-errors-on-localhost-in-2020-5a656ed8cefa#:~:text=1.,setting%20in%20Create%20React%20App&text=%22proxy%22%3A%20%22https%3A%2F%2F,CORS%20error%20will%20be%20resolved.
【讨论】:
【参考方案7】:两个可能的答案:
-
在您的 WebConfig 文件中配置 cors。从春天开始Documentation
你的方法是这样的:
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins("https://localhost:3000/**")
.allowedMethods("PUT", "DELETE","GET","POST");
// Add more mappings...
为了进行测试,请将您的 @CrossOrigin 更改为所有来源:
@CrossOrigin(origins =*)
如果它有效,那么它只是某个地方的一个细节。你能测试一下并告诉我们吗?
查看文档,他们总是留下明确的'origins="address"'。在您的事业中,它将是:
@CrossOrigin(origins ="http://localhost:3000")
【讨论】:
在CrossOrigin
,value
是aliased 到origins
所以我认为@CrossOrigin("http://localhost:3000")
和@CrossOrigin(origins ="http://localhost:3000")
应该做同样的想法,不是吗?
是的。是一样的,但是当我遇到一些麻烦的时候,我什么都清楚了。这就是为什么我在最后一个论点中说的原因【参考方案8】:
使用
@CrossOrigin(origins = "http://localhost:3000")
【讨论】:
虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高答案的长期价值。 另一个答案已经建议使用@CrossOrigin
在CrossOrigin
,value
是aliased 到origins
所以我认为@CrossOrigin("http://localhost:3000")
和@CrossOrigin(origins ="http://localhost:3000")
应该做同样的想法,不是吗?以上是关于CORS 标头“Access-Control-Allow-Origin”缺少 REACT的主要内容,如果未能解决你的问题,请参考以下文章
CORS - 从 Postman 伪造 CORS 预检无法返回标头