3

I've actually crate an angular service to get data from the server which running on 'localhost:8080/' (endpoint /user) . But when I serve the angular project on 'localhost:4200' it made this Error :Access to XMLHttpRequest at 'localhost:8080/user' from origin ..

I tried to solve this problem by adding @CrossOrigin(origins = "*") in the controller and I add a proxy.conf.json in the angular project like I found here : 'https://angular.io/guide/build' But the problem persist .

this is the angular service :

  @Injectable({
  providedIn: 'root'
})
export class RestService {
  api = 'localhost:8080/user'
  constructor(private http: HttpClient) { }
  getUsers(): Observable<String> {
    return this.http.get<String>(this.api);
  }
}

this is my proxy.conf.json :

{
    "/*": {
        "target": "http://localhost:8080",
        "secure": false,
        "logLevel": "debug"
    }
}

this is the conf in angular.json :

"serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "crud:build",
            "proxyConfig": "src/proxy.conf.json"
          }

and this is the spring boot controller :

@RestController
@CrossOrigin(origins = "*")

public class userController {
    @GetMapping("/user")
    public String getuser(){
        return "the user name is bilel" ;
    }
}
2
  • I don't know if "/*" is supported. But it is for your interest to prefix all the backend calls with /api or /backend, then you could use /api in your proxy conf (it will make things easier for your Apache/Nginx conf later). Also, you must chose, either you handle this on frontend side (with the proxy, as you did) or from the backend side, with the @CrossOrigin but not both. IMHO, @CrossOrigin(origins = "*") is a very bad idea (absolute anti-pattern). Also, can you try to add changeOrigin:true in your proxy conf ? Commented Mar 21, 2022 at 14:32
  • thank you very much for this advice I try "/* " and I found that is not supported : 'Error: [HPM] Invalid context. Expecting something like: "/api" ' Commented Mar 21, 2022 at 17:55

2 Answers 2

3

To build onto @Alain Boudard's answer, you need to add a path rewrite:

export class RestService {
  baseUrl = 'api/user'

  constructor(private http: HttpClient) { }

  getUsers(): Observable<string> {
    return this.http.get<string>(this.baseUrl);
  }
}

and the in the proxy.conf.json file, don't forget the pathRewrite so that 'api' is deleted from the URL before the call is made to the backend:

{
  "/api/*": {
    "target": "http://localhost:8080",
    "secure": false,
    "logLevel": "debug",
    "changeOrigin": true,
    "pathRewrite": {
      "^/api": ""
    }
  }
}

PS: By the way, you will very rarely need to use type String, instead use the primitive string (lowercase s): https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html

Sign up to request clarification or add additional context in comments.

2 Comments

I wanted to thank you for the advice of the string using , but I didn't understand the utility of the pathRewrite
if you don't use the pathRewrite the url you are trying to reach on the backend is localhost:8080/api/user, with the pathRewrite, you do not need to change the implementation of your backend, it will call the backend on the localhost:8080/user url just like in your original question
1

You would not want to tell your Angular service about the target server and its port, it's against the use of the proxy conf.

Call something like a generic api/ root endpoint and map it :

export class RestService {
  api = '/api/user'
  constructor(private http: HttpClient) { }
  getUsers(): Observable<String> {
    return this.http.get<String>(this.api);
  }
}

And the proxy like that :

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

3 Comments

for this to work you need to add a path rewrite to the configuration of the proxy so that the additional api in the url is deleted before the request is sent to the backend
Well, it depends of course on the endpoints you declared in your Spring controllers, and /api is merely a convention, you're right :)
thank you very much I resolve this problem , but unfortunately I have another Unexpected token h in JSON at position 1 at JSON.parse (<anonymous>) at XMLHtt…, text: 'the user name is bilel' and I m trying to solve it .. thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.