• 【SpringBoot】No 'Access-Control-Allow-Origin' header is present on the requested resource.


    关键字:跨域,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"]

    参考:java-encodeURI decodeURI 解决地址传参乱码问题

    为天地立心,为生民立命,为往圣继绝学,为万世开太平。
  • 相关阅读:
    Android Facebook分享功能实现
    Facebook KeyHash生成方法
    Android 版 Facebook 登录
    在Android App中集成Google登录
    Android 应用程序集成FaceBook 登录及二次封装
    Android Facebook和Twitter登录和分享完整版
    android开发之自定义圆形ImagView
    Okhttp、Volley和Gson的简单介绍和配合使用
    Android并发编程
    重要的ui组件——Behavior
  • 原文地址:https://www.cnblogs.com/rxx1005/p/12527240.html
Copyright © 2020-2023  润新知