【问题标题】:How to fix 'Access-Control-Allow-Origin' error using (Angular js+springboot)如何使用(Angular js+springboot)修复“Access-Control-Allow-Origin”错误
【发布时间】:2019-08-07 17:15:19
【问题描述】:

当从 Angular 服务发送请求到 java 控制器时,我遇到了错误

 No 'Access-Control-Allow-Origin' 

1.http://localhost:8080/fileValidate403

2.Access to XMLHttpRequest at 'http://localhost:8080/fileValidate' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

    # Angular-Service

   1.below is my angular service code.

      createFileValidation(filevalidation: Filevalidation): Observable<any> {
                var service = "http://localhost:8080/fileValidate";
                let body = JSON.stringify(filevalidation);
                let headers = this.createHeader();
                headers.append('Content-Type', 'application/json');
                headers.append('Access-Control-Allow-Origin', '*');
                headers.append('Access-Control-Allow-Methods', 'OPTIONS,GET, POST, PUT, PATCH, DELETE');
                headers.append('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
                headers.append('Access-Control-Allow-Credentials', 'true');
                //  let options = new RequestOptions({ headers: headers });
                return this.http
                    .post(service, body, { headers: headers })
                    .map((response: Response) => {
                        return response.json(); //blob should be use insted of json
                        //return new Blob([response.blob()], { type: 'text/xml' });
                    });
            }
        }

1.下面是我的JAVA控制器代码。

@RestController
@CrossOrigin(origins = "http://localhost:8080/fileValidate")
public class FileValidationController {
    @Autowired
    private FileValidationService fileService;
    String results = "success";
    @RequestMapping(value = "/fileValidate", method = RequestMethod.GET, produces = { "application/json" })
    @ResponseBody
    public ResponseEntity<String> fileService() {
        System.out.println("Controller");
        HttpHeaders headers = new HttpHeaders();
        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Methods", "OPTIONS,GET, POST, DELETE, PUT");
//        .allow("OPTIONS").build();
        return new ResponseEntity<String>(fileService.validatefile(),headers, HttpStatus.OK);

    }
}

下面的代码是代理设置

{
    "/api": {
      "target": "http://localhost:8080",
      "secure": false
    }
  }

Angular package.json 这里我已经做了代理设置请看脚本

{

  "scripts": {
    "ng": "ng",
    "start": "ng serve --proxy-config proxy.config.json",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  1. 从 Postman 我可以发送相同的请求,但是当我从浏览器发送相同的请求时,我收到了这个错误,所以我的期望是请求应该到达 JAVA 控制器。

2.在这个问题上我真的需要帮助,我已经尝试了所有可能的解决方案

【问题讨论】:

标签: angular spring-boot


【解决方案1】:

请求被阻止,因为 localhost:8080 与 localhost:4200 是不同的 URL。

您必须了解是浏览器阻止了请求,而不是 Web 服务器。浏览器可能会加载资源,但由于某些网络标准,它会阻止它。

一种选择是使用相同的端口,以便获得相同的 URL。

另一个选项是允许其他 URL/来源。

因此,您的网络服务器必须使用此标头进行响应:

Access-Control-Allow-Origin: http://localhost:4200

或允许所有来源:

Access-Control-Allow-Origin: *

编辑:

您现在尝试添加标题但出现错误:

  1. 不要将 Access-Control-Allow-* 标头添加到您的客户端代码中。它们从服务器发送到客户端。
  2. 在这一行

    @CrossOrigin(origins = "http://localhost:8080/fileValidate")

    您允许错误的来源。来源是http://localhost:4200

如果您仍然收到 No 'Access-Control-Allow-Origin' 错误,您可以在浏览器中分析网络流量(Firefox 中的 F12)。查看是否发送了标头以及它的值是什么。

可能还需要设置其他 Access-Control-Allow-* 标头,但您会收到不同的错误消息。

【讨论】:

  • 我使用了两个选项。 1- @CrossOrigin(origins = "*", allowCredentials = "true", methods = {RequestMethod.OPTIONS, RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}) ,
  • 2.我为 CORS Origin 配置创建了一个 WebConfig 类,但结果与我得到的错误相同
【解决方案2】:

当您使用 Spring Boot 时,为什么不添加过滤器。举个例子吧。

@Component
public class SimpleCORSFilter implements Filter {

    private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

    public SimpleCORSFilter() {
        log.info("SimpleCORSFilter init");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

}

我们在这里做什么? 我们通过特定的 HTTP 标头启用一些 CORS 功能,告诉浏览器应该允许下载的网页向给定/所有域发出 Web 请求。

您还可以在此限制 HTTP 方法(GET/PUT/POST/DELETE 等)。

如果您需要更多信息,请告诉我。快乐编码

【讨论】:

  • 仍然面临同样的错误。即使我添加了过滤器
【解决方案3】:

问题是因为您的客户端应用程序和服务器应用程序在不同的域中运行。浏览器会在调用 API 之前调用options 来检查安全性。

即使您在客户端应用程序标头中添加Access-Control-Allow origin header 也无法解决。

服务器端解决方案

您必须使用任何库在服务器应用程序中启用 CORS,或者您必须在后端应用程序中处理 options 调用。

处理 options 呼叫,因为您已经解决了带有 200 响应的选项呼叫。

对于每个 API,您必须检查方法和 if 选项方法,然后使用 200 解决

角度解决方案

在根目录下创建proxy.conf.json

<!-- proxy.conf.json -->
{
    "/api/*": {
        "target": "http://localhost:8080",
        "secure": true,
        "logLevel": "debug"
    }
}

更改 package.json 中的启动脚本

<!-- package.json -->
{.
 .
 .
 "scripts": {
        "start": "ng serve --proxy-config proxy.conf.json",
         .
         .
           }

将 Angular 应用程序 API 调用的基本 URL 更改为 /api/

而不是ng serve 运行npm start

在进行上述更改时,不会出现CORS 问题

注意:您的服务器 API 端点应该是这样的 http:localhost:8000/api/fileValidate

注意在上面我将/api添加到API端点并在proxy.conf.json中配置了相同的内容

希望它能解决您的问题。如果您遇到任何困难,请告诉我。

【讨论】:

  • 这对我不起作用,我仍然面临同样的问题
  • 你试过什么?以spring-bootAngular 方式处理OPTIONS 调用。如果您在 Angular 中尝试过并遵循上述所有配置,那么您必须运行 npm start。此外,您还必须将 API 端点从 http://localhost:8000/fileValidate 更改为 http://localhost:8000/api/fileValidate
  • 现在我使用了localhost:8000/api/fileValidate,但仍然遇到同样的问题,代理设置对于代理来说看起来也不错,我正在使用“proxy.config.json”和“package.json”,我不明白为什么同样的问题来了。 Angular 服务向 URL“localhost:8000/api/fileValidate”发送请求,在我的控制器中我使用了相同的 URL“localhost:8000/api/fileValidate”,但请求没有击中我的控制器
猜你喜欢
  • 2018-12-12
  • 2020-08-18
  • 2016-08-28
  • 2020-12-14
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
  • 2018-12-12
相关资源
最近更新 更多