Angular的GET方法始终进入错误部分。

huangapple go评论113阅读模式
英文:

angular get method always going to error part

问题

I am writing an application in Angular with Java. Here, I am writing a GET method in Angular, which is sending a request to the frontend. The backend Java service is returning a list of objects. However, the Angular GET method is encountering an error.

Java service:-

@GetMapping(value = "/getStatusMails")
public ResponseEntity<Object> getStatusMails() {
    List<Dto> status = service.getStatusMails(123);
    return new ResponseEntity<Object>(status, HttpStatus.OK);
}

Angular GET method: -

this.httpClient.get<any>('http://IP:8090/getStatusMails').subscribe(
    data => this.elements = data,
    error => console.error('There was an error!', error)
)

I have tested it with Postman, and it is returning the proper list of objects.

My console error: -

Access to XMLHttpRequest at 'http://IP:8090/getStatusMails' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
zone-evergreen.js:2845 GET http://IP:8090/getStatusMails net::ERR_FAILED
core.js:6241 ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://IP:8090/getStatusMails", ok: false, …}

If I write my code like below

const url = "http://IP:8090/getStatusMails"; // site that doesn’t send Access-Control-*
fetch(url)
    .then(response => response.text())
    .then(contents => console.log(contents))
    .catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
}

In my console, I am getting the message Can’t access http://IP:8090/getStatusMails response. Blocked by browser? When I click on my URL in the log, I am able to see the output in another window.

Angular的GET方法始终进入错误部分。

Angular的GET方法始终进入错误部分。

英文:

I am writing a application in angular with java. Here I am writing a get method in angular, it is going to front end and the back end java service is returning a list of object. But the angular get method is directly going to error part.

Java service:-

    @GetMapping(value = &quot;/getStatusMails&quot;)
	public ResponseEntity&lt;Object&gt; getStatusMails() {
		List&lt;Dto&gt; status= sercice.getStatusMails(123);
		return new ResponseEntity&lt;Object&gt;(status, HttpStatus.OK);
	}

angular get method: -

    this.httpClient.get&lt;any&gt;(&#39;http://IP:8090/getStatusMails&#39;).subscribe(
    data =&gt; this.elements = data,
    error =&gt; console.error(&#39;There was an error!&#39;, error))

I have tested with postman, it is getting the proper list of objects.

My console error: -

Access to XMLHttpRequest at &#39;http://IP:8090/getStatusMails&#39; from origin &#39;http://localhost:4200&#39; has been blocked by CORS policy: No &#39;Access-Control-Allow-Origin&#39; header is present on the requested resource.
zone-evergreen.js:2845 GET http://IP:8090/getStatusMails net::ERR_FAILED
core.js:6241 ERROR HttpErrorResponse&#160;{headers: HttpHeaders, status: 0, statusText: &quot;Unknown Error&quot;, url: &quot;http://IP:8090/getStatusMails&quot;, ok: false,&#160;…}

If I write my code like below

const url = &quot;http://IP:8090/getStatusMails&quot;; // site that doesn’t send Access-Control-*
    fetch(url)
    .then(response =&gt; response.text())
    .then(contents =&gt; console.log(contents))
    .catch(() =&gt; console.log(&quot;Can’t access &quot; + url + &quot; response. Blocked by browser?&quot;))
}

In my console I am getting the console like Can’t access http://IP:8090/getStatusMails response. Blocked by browser? When I click on my url in the log, I am able to see the output in another window.

Angular的GET方法始终进入错误部分。

Angular的GET方法始终进入错误部分。

答案1

得分: 3

Http错误代码0是由CORS引起的:您的Angular应用程序托管在与您的Java应用程序不同的主机上,XHR请求被禁止。

要解决此问题,您可以选择使用反向代理(推荐)或在后端添加访问控制HTTP标头。

使用反向代理

在开发期间

在与您的package.json文件相同的文件夹中创建一个proxy.json文件:

{
    "/getStatusMails": {
        "target": "http://IP:8090",
        "secure": false,
        "changeOrigin": true
    }
}

然后使用--proxy-config proxy.json启动您的Angular开发服务器:

ng serve --proxy-config proxy.json

现在,您可以简单地请求/getStatusMails,而不是发送请求到http://IP:8090/getStatusMails

如果您有多个服务,可以为它们定义一个共同的前缀(例如/api/rest):

  • /api/getStatusMails
  • /api/getUsers

(尽管我建议遵循REST命名约定)。

然后使用前缀配置代理:

{
    "/api": {
        "target": "http://IP:8090",
        "secure": false,
        "changeOrigin": true
    }
}

在生产环境中,您要么必须在同一个Java服务器上部署所有内容,要么必须在您的Web服务器(Apache Httpd或Nginx)中配置反向代理。

Apache Httpd

您必须启用mod_proxy,然后可以使用ProxyPassProxyPassReverse进行配置:

ProxyPass         "/getStatusMails" "http://IP:8090/"
ProxyPassReverse  "/getStatusMails" "http://IP:8090/"

您可以在Apache Http文档中找到更多信息。

Nginx

使用proxy_path属性:

location /getStatusMails {
    proxy_pass http://IP:8090/;
}

您可以在Nginx文档中找到更多信息。

使用访问控制HTTP标头

在此配置中,用户的Web浏览器将在发送实际XHR请求之前发送OPTION请求。

您的Java应用程序必须发送Access-Control-Allow-OriginAccess-Control-Allow-Methods标头以允许跨源请求。

例如,在开发期间,您可以发送:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST

以允许来自任何URL的GET和POST请求。

在生产中,您永远不应该使用*,而应该始终指定前端的实际URL。

由于您似乎在使用Spring,您可以简单地使用@CrossOrigin注释您的方法来发送这些标头。您可以在Spring文档中找到更多信息。

英文:

Http error code 0 is caused by CORS: your Angular application is hosted on a different host than your Java application and XHR requests are forbidden.

To solve this, you can either use a reverse proxy (recommended) or add Access Control http headers to your backend.

Using a reverse proxy

During development

Create a proxy.json file in the same folder than your package.json:

{
    &quot;/getStatusMails&quot;: {
        &quot;target&quot;: &quot;http://IP:8090&quot;,
        &quot;secure&quot;: false,
        &quot;changeOrigin&quot;: true
    }
}

And start your Angular dev server with --proxy-config proxy.json :

ng serve --proxy-config proxy.json

Now instead of sending a request to http://IP:8090/getStatusMails, you can simply request /getStatusMails.

If you have multiple services, you can define a common prefix for them (like /api or /rest):

  • /api/getStatusMails
  • /api/getUsers

(Although I would recommend following REST naming conventions).

And then configure the proxy using the prefix:

{
    &quot;/api&quot;: {
        &quot;target&quot;: &quot;http://IP:8090&quot;,
        &quot;secure&quot;: false,
        &quot;changeOrigin&quot;: true
    }
}

In production, you either have to deploy everything on the same Java server or you have to configure a reverse proxy in your web server (Apache Httpd or Nginx).

Apache Httpd

You have to enable mod_proxy and then you can configure it with ProxyPass and ProxyPassReverse:

ProxyPass         &quot;/getStatusMails&quot; &quot;http://IP:8090/&quot;
ProxyPassReverse  &quot;/getStatusMails&quot; &quot;http://IP:8090/&quot;

You can find more information on Apache Http documentation.

Nginx

Using proxy_path property:

location /getStatusMails {
    proxy_pass http://IP:8090/;
}

You can find more information on Nginx documentation.

Using Access Control http headers

In this configuration, user's web browser will send an OPTION request before sending the real XHR request.

Your Java application have to send Access-Control-Allow-Origin and Access-Control-Allow-Methods headers to allow cross origin requests.

For example, during development you could send:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST

To allow GET and POST requests from any URLs.

In production, you should never use * and always specify the real URL of your frontend.

Since you seems to be using Spring, you can simply annotate your method with @CrossOrigin to send these headers. You can find more information about this in  Spring documentation.

答案2

得分: 1

This is a CORS error.

This occurs when your client is running on a different server than that of backend.

so why this doesn't occur in Postman?

  • Postman is for development purpose and doesn't have any built-in checks for the origin

why does this happen in the browser?

  • Browsers check for origin to prevent CSRF attacks.

The solution to your problem is to add your client's URL in 'Allow-Acess-Control_origin' at your server-side.
check this on how to do that.

you can either set 'Allow-Acess-Control_origin' to * , (accept all connections)
or you can specify the client URL's

英文:

This is a CORS error.

This occurs when your client is running on a different server than that of backend.

so why this doesn't occur in Postman?

  • postman is for development purpose and doesn't have any built-in checks for the origin

why does this happen in the browser?

  • browsers checks for origin to prevent CSRF attacks.

The solution to your problem is to add your client's URL in 'Allow-Acess-Control_origin' at your server-side.
check this on how to do that.

you can either set 'Allow-Acess-Control_origin'to * , (accept all connections)
or you can specify the client URL's

答案3

得分: 0

Adding @CrossOrigin annotation to your controller in your Java service should fix your issue.

@CrossOrigin
@GetMapping(value = "/getStatusMails")
public ResponseEntity<Object> getStatusMails() {
    List<Dto> status = service.getStatusMails(123);
    return new ResponseEntity<Object>(status, HttpStatus.OK);
}
英文:

Adding @CrossOrigin annotation to your controller in your Java service should fix your issue.

@CrossOrigin
@GetMapping(value = &quot;/getStatusMails&quot;)
    public ResponseEntity&lt;Object&gt; getStatusMails() {
        List&lt;Dto&gt; status= sercice.getStatusMails(123);
        return new ResponseEntity&lt;Object&gt;(status, HttpStatus.OK);
    }

huangapple
  • 本文由 发表于 2020年8月3日 19:49:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63228887.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定