关键字:跨域
,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
里面少放点参数,发起异步请求,竟然成功了。。。
:
| |
| 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)) |
| |
转码前,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"]
参考:java-encodeURI decodeURI 解决地址传参乱码问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)