首页  编辑  

Spring大文件上传导致前端报跨域异常错误

Tags: /Java/   Date Created:

SpringBoot 大文件上传与浏览器报错冲突


It's not SpringBoot's bug, You SHOULD NOT allow CORS request
这不是 SpringBoot 的缺陷,而是你违反了安全规则导致的问题,在同源下不会报这个错误。
具体说明:
  1. 环境, SpringBoot 2.7.7,Spring v5.3.24,Embed Apache Tomcat/9.0.70,Chrome v113.0.5672.64(64-bit)
  2. 服务器设置max-file-size为5MB, max-request-size: 5MB
  3. Chrome和PostMan上传小文件功能正常,能正常上传。
  4. 在PostMan中,用大文件,服务器正确处理,GlobalExceptionHandler能中断,也能返回错误JSON信息给PostMan并显示,一切符合预期。
  5. 在Chrome前端网页中,上传大文件,会报错: net::ERR_CONNECTION_RESET,浏览器开发控制台可以看到Response完全没有,为空。
后端日志报错:
org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (76822227) exceeds the configured maximum (5000000)
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.init(FileItemIteratorImpl.java:150) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.getMultiPartStream(FileItemIteratorImpl.java:194) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.findNextItem(FileItemIteratorImpl.java:213) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.<init>(FileItemIteratorImpl.java:131) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:255) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:279) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.connector.Request.parseParts(Request.java:2869) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.connector.Request.getParts(Request.java:2771) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1098) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:95) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:88) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:87) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1178) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1012) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_151]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_151]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_151]

查相关资料和网页,按网络上设置 max-swallow-size: -1之后,浏览器中可以看到错误变成 CORS error,response 变成下面的,但还是无法看到返回的错误JSON内容:
同样的请求,在PostMan中,可以看到正常的结果:
这个问题的具体原因是:
SpringBoot中,如果是Reqeust的请求超大,那么这个报错是非常非常底层的,哪怕我们在 @Configuration 中,配置了 registry.addMapping("/**").allowedMethods("GET", "POST");允许所有请求CROS,这个错误会直接返回前端,从而丢失Response Header中的  Access-Control-Allow-Origin: * ,导致前端报 CORS 错误。
下面的代码,不能保证 MaxUploadSizeExceededException 也能够返回正确的CORS头信息:
  1. import org.springframework.context.annotation.Configuration;
  2. import org.springframework.web.servlet.config.annotation.CorsRegistry;
  3. import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  4. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  5. /**
  6.  * CORS configuration
  7.  */
  8. @Configuration
  9. public class WebMvcConfig implements WebMvcConfigurer {
  10.   /**
  11.    * Allow CORS Request, DON'T remove this
  12.    *
  13.    * @param registry registry
  14.    */
  15.   @Override
  16.   public void addCorsMappings(CorsRegistry registry) {
  17.     registry.addMapping("/**").allowedMethods("GET", "POST");
  18.   }
  19. }

Solution: 总结一下SpringBoot大文件上传的注意事项:
  1. 必须设置 application propertie: server.tomcat.max-swallow-size: -1 ,保证Spring读取超大Body能继续处理,否则会报net::ERR_CONNECTION_RESET。
  2. 全局 ExceptionHandler 中,如果是跨域请求的,必须单独处理 MaxUploadSizeExceededException,在响应中,必须手动设置 Header中的  Access-Control-Allow-Origin: * 。这个在同源请求中是不存在问题的,跨域必须设置,否则浏览器中也会报错。
  1. import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
  2. import org.springframework.http.HttpHeaders;
  3. import org.springframework.http.ResponseEntity;
  4. import org.springframework.web.bind.annotation.ExceptionHandler;
  5. import org.springframework.web.bind.annotation.RestControllerAdvice;
  6. import org.springframework.web.multipart.MaxUploadSizeExceededException;
  7. import javax.servlet.http.HttpServletResponse;
  8. /**
  9.  * Global Controller Exception Aspect
  10.  * <p>
  11.  * This handler only parse common exceptions, DON'T parse special exception here
  12.  */
  13. @RestControllerAdvice
  14. public class GlobalControllerExceptionHandler {
  15.   @ExceptionHandler(MaxUploadSizeExceededException.class)
  16.   public ResponseEntity<Object> parseSizeLimitExceededException(SizeLimitExceededException exception, HttpServletResponse response) {
  17.     response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); // <--- 这一行是解决关键
  18.     return logObject("File size exceed limitation: " + exception.getPermittedSize(), exception);
  19.   }
  20. }


%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20edge%3D%221%22%20source%3D%223%22%20target%3D%2210%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%223%22%20value%3D%22%22%20style%3D%22image%3Baspect%3Dfixed%3Bhtml%3D1%3Bpoints%3D%5B%5D%3Balign%3Dcenter%3BfontSize%3D14%3Bimage%3Dimg%2Flib%2Fazure2%2Fgeneral%2FBrowser.svg%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%2240%22%20y%3D%22254%22%20width%3D%2265%22%20height%3D%2252%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%224%22%20value%3D%22%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20edge%3D%221%22%20source%3D%226%22%20target%3D%228%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%225%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BentryX%3D0.477%3BentryY%3D0.981%3BentryDx%3D0%3BentryDy%3D0%3BentryPerimeter%3D0%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20edge%3D%221%22%20source%3D%226%22%20target%3D%223%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22429%22%20y%3D%22374%22%20as%3D%22targetPoint%22%2F%3E%3CArray%20as%3D%22points%22%3E%3CmxPoint%20x%3D%22429%22%20y%3D%22330%22%2F%3E%3CmxPoint%20x%3D%2271%22%20y%3D%22330%22%2F%3E%3C%2FArray%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%226%22%20value%3D%22SpringBoot%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2014px%3B%26quot%3B%26gt%3BparseRequest%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3BverticalAlign%3Dmiddle%3BlabelBackgroundColor%3Ddefault%3BfontSize%3D14%3BfontFamily%3DTahoma%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22355%22%20y%3D%22250%22%20width%3D%22134%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%227%22%20value%3D%22%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20edge%3D%221%22%20source%3D%228%22%20target%3D%2212%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%228%22%20value%3D%22SpringBoot%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2014px%3B%26quot%3B%26gt%3BaddCorsMappings%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2014px%3B%26quot%3B%26gt%3BAccess-Control-Allow-Origin%3A%20*%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3BverticalAlign%3Dmiddle%3BlabelBackgroundColor%3Ddefault%3BfontSize%3D14%3BfontFamily%3DTahoma%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22525%22%20y%3D%22250%22%20width%3D%22200%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%229%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BexitX%3D1%3BexitY%3D0.5%3BexitDx%3D0%3BexitDy%3D0%3BentryX%3D0%3BentryY%3D0.5%3BentryDx%3D0%3BentryDy%3D0%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20edge%3D%221%22%20source%3D%2210%22%20target%3D%226%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2210%22%20value%3D%22SpringBoot%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2014px%3B%26quot%3B%26gt%3B%26lt%3Bdiv%20style%3D%26quot%3Bfont-size%3A%2014px%3B%26quot%3B%26gt%3B%40RestControllerAdvice%26lt%3B%2Fdiv%26gt%3BExceptionHandler%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3BverticalAlign%3Dmiddle%3BlabelBackgroundColor%3Ddefault%3BfontSize%3D14%3BfontFamily%3DTahoma%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22151%22%20y%3D%22250%22%20width%3D%22159%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2211%22%20value%3D%22%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20edge%3D%221%22%20source%3D%2212%22%20target%3D%2213%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2212%22%20value%3D%22SpringBoot%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2014px%3B%26quot%3B%26gt%3BController%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3BverticalAlign%3Dmiddle%3BlabelBackgroundColor%3Ddefault%3BfontSize%3D14%3BfontFamily%3DTahoma%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22755%22%20y%3D%22250%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2213%22%20value%3D%22SpringBoot%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2014px%3B%26quot%3B%26gt%3BService%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3BverticalAlign%3Dmiddle%3BlabelBackgroundColor%3Ddefault%3BfontSize%3D14%3BfontFamily%3DTahoma%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22905%22%20y%3D%22250%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2214%22%20value%3D%22SizeLimitExceededException%26%2310%3B%E8%8B%A5server.tomcat.max-swallow-size%20%26lt%3B%26gt%3B%20-1%26%2310%3B%E6%8A%A5%C2%A0net%3A%3AERR_CONNECTION_RESET%20%E9%94%99%E8%AF%AF%22%20style%3D%22shape%3Dcallout%3BwhiteSpace%3Dwrap%3Bperimeter%3DcalloutPerimeter%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3Bsize%3D20%3Bposition%3D0.47%3BlabelPosition%3Dcenter%3BverticalLabelPosition%3Dmiddle%3Balign%3Dcenter%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22293.5%22%20y%3D%22150%22%20width%3D%22276.5%22%20height%3D%2290%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2215%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bdashed%3D1%3Bhtml%3D1%3BstrokeWidth%3D3%3Brounded%3D0%3BfontSize%3D14%3BfontFamily%3DTahoma%3BverticalAlign%3Dmiddle%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22505%22%20y%3D%22410%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%22505%22%20y%3D%22224%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2216%22%20value%3D%22%E5%8F%B3%E8%BE%B9%E7%AB%96%E7%BA%BF%E4%B9%8B%E5%89%8D%E7%9A%84%E5%BC%82%E5%B8%B8%EF%BC%8C%E5%85%A8%E9%83%A8%E9%9C%80%E8%A6%81%E6%89%8B%E5%8A%A8%E8%AE%BE%E5%AE%9A%20CORS%26%2310%3B%E8%8B%A5%E6%B2%A1%E6%9C%89%E8%AE%BE%E5%AE%9ACORS%EF%BC%8C%E6%8A%A5CORS%20error%22%20style%3D%22text%3BwhiteSpace%3Dwrap%3Balign%3Dright%3BfontSize%3D14%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22120%22%20y%3D%22340%22%20width%3D%22384%22%20height%3D%2250%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2217%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BexitX%3D0.1%3BexitY%3D0.5%3BexitDx%3D0%3BexitDy%3D0%3BexitPerimeter%3D0%3B%22%20edge%3D%221%22%20source%3D%2218%22%20target%3D%223%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CArray%20as%3D%22points%22%3E%3CmxPoint%20x%3D%22770%22%20y%3D%22410%22%2F%3E%3CmxPoint%20x%3D%2270%22%20y%3D%22410%22%2F%3E%3C%2FArray%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2218%22%20value%3D%22%22%20style%3D%22shape%3DcurlyBracket%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Brounded%3D1%3BflipH%3D1%3BlabelPosition%3Dright%3BverticalLabelPosition%3Dmiddle%3Balign%3Dleft%3BverticalAlign%3Dmiddle%3Brotation%3D90%3Bsize%3D0.5%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22760%22%20y%3D%22115%22%20width%3D%2220%22%20height%3D%22500%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2219%22%20value%3D%22%E7%AB%96%E7%BA%BF%E5%90%8E%E7%9A%84%E5%BC%82%E5%B8%B8%E5%9D%87%E8%83%BD%E6%AD%A3%E5%B8%B8%E5%A4%84%E7%90%86%22%20style%3D%22text%3BwhiteSpace%3Dwrap%3Balign%3Dcenter%3BfontSize%3D14%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22658%22%20y%3D%22330%22%20width%3D%22224%22%20height%3D%2250%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E