如何使用(Angular js + springboot)修复'Access-Control-Allow-Origin'错误

时间:2019-08-01 10:20:47

标签: angular spring-boot

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

 No 'Access-Control-Allow-Origin' 

1。http://localhost:8080/fileValidate 403

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。确实,我需要在此问题上寻求帮助,我已经尝试了所有可能的解决方案

3 个答案:

答案 0 :(得分:1)

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

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

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

另一种选择是允许其他URL /来源。

因此,您的Web服务器必须使用以下标头进行响应:

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

如果仍然出现没有“ Access-Control-Allow-Origin” 错误,则可以分析浏览器中的网络流量(firefox中为F12)。查看是否发送了标头,以及标头的值是什么。

可能还需要设置其他Access-Control-Allow- *标头,但随后您将收到其他错误消息。

答案 1 :(得分:0)

使用Spring Boot时,为什么不添加Filter。让我举一个例子。

@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等)。

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

答案 2 :(得分:0)

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

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

服务器端解决方案

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

处理options调用,即您已解决带有200个响应的选项调用。

对于每个要检查方法的API,如果使用options方法,则应使用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

中进行了配置

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