關鍵字:跨域,Access-Control-Allow-Origin,轉碼,解碼
在做一個前后端分離項目,本來前端項目都可以正常訪問后端接口,跨域是這么設置的,接口可以正常訪問
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
但是在訪問一個新的接口時,前端控制台錯誤:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
后端錯誤:
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:468) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) [tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591) [tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.29.jar:9.0.29]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.29.jar:9.0.29]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]
在網上找了一下解決方法,都是說跨域問題
參考:response設置響應頭,解決跨域請求問題,No ‘Access-Control-Allow-Origin’ header is present on the requested resource
解決方法:
1、加注解----對我沒用。。。
@CrossOrigin //跨域
public class BookController {
}
2、設置響應頭----還是不行。。。
@PostMapping(path = "/add")
public JsonResult<Object> addBook(Book book, HttpServletResponse response) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Cache-Control", "no-cache");
}
3、不要參數,試一下,竟然好了。。。。看來出現這個問題的原因是參數的原因
前端請求:
this.$axios({method: 'post', url: '/book/add'}).then(res => {
console.log(res.data)
}).catch(res => {
});
后端接口:
@PostMapping(path = "/add")
public JsonResult<Object> addBook() {
}
又看到一篇文章說可能是參數太多:
參考:Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors will ***
那就繼續試,這是我原來要傳的參數:
book: {
name: '',
author: '',
type: '',
publishHouse: '',
price: 0,
description: '',
number: 0,
sales: 0,
status: true,
image: ''
},
我又重新寫了一個jsonData,作為參數來代替上面的book
bookTest: {},
先給bookTest里面少放點參數,發起異步請求,竟然成功了。。。:
//給里面少放點數據
this.bookTest.name = this.book.name;
this.bookTest.author = this.book.author;
this.bookTest.type = this.book.type;
this.$axios({method: 'post', url: '/book/add', params: this.bookTest})
.then(res => {
console.log(res.data)
}).catch(res => {
});
后端代碼:
@RequestMapping(path = "/book")
public class BookController {
@PostMapping(path = "/add")
public JsonResult addBook( Book newBook) {
System.out.println("addBook");
System.out.println(newBook);
JsonResult<Object> result = new JsonResult<>();
result = result.builder().data(newBook).message("添加成功").code("1").build();
return result;
}
}
繼續增加參數,除了this.bookTest.image = this.book.image;:
this.bookTest.name = this.book.name;
this.bookTest.author = this.book.author;
this.bookTest.type = this.book.type;
this.bookTest.publishHouse = this.book.publishHouse;
this.bookTest.price = this.book.price;
this.bookTest.description = this.book.description;
this.bookTest.number = this.book.number;
this.bookTest.sales = this.book.sales;
this.bookTest.status = this.book.status;
仍然可以接收參數,但是加上this.bookTest.image = this.book.image;就又開始報這個錯誤了,看來問題就是出在了這個image上。
下圖的image有問題

2020.3.7更新:
問題已經找出,就出在了image字符串上,因為image這個字符串有特殊字符,必須先轉碼,傳輸到后端,再解碼
前端:轉碼,對有特殊字符的字符串進行轉碼
this.book.image= encodeURI(JSON.stringify(imageArray))
//imageArray是一個數組,JSON.stringify()是把數組轉為字符串,encodeURI()是轉碼的
轉碼前,image是這樣的:
["/images/ac57249167ce4af5.jpg","/images/9d7bf84bdf40e030.jpg"]
轉碼后,image是這樣的:
%22/images/ac57249167ce4af5.jpg%22%7D,%22/images/9d7bf84bdf40e030.jpg%22%7D%5D
后端:解碼
@PostMapping(path = "/a")
public JsonResult add(Book book) {
String imageJson= URLDecoder.decode(book.getImage(),"utf-8" );
return null;
}
解碼前:后端接收到的book.getImage()就是前端轉碼后的樣子:
%22/images/ac57249167ce4af5.jpg%22%7D,%22/images/9d7bf84bdf40e030.jpg%22%7D%5D
解碼后:
["/images/ac57249167ce4af5.jpg","/images/9d7bf84bdf40e030.jpg"]
