1

I'm creating an interface for hackers news with angular 7. Normally I use the public APIs available, but for login services they are not available.

I'm trying to make a POST call, as done by an OpenSource Android Client app for HN, specifically in this file: https://github.com/hidroh/materialistic/blob/master/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServicesClient.java to the url https://news.ycombinator.com/login , setting the username, password and redirect as parameters.

Unfortunalty my request is blocked by the CORS policy.

I performed the test with Postman and instead works perfectly.

This is my code:

const payload = {
  'acct': 'username',
  'pw': 'password',
  'goto': 'news'
};

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE, HEAD',
    'Access-Control-Allow-Headers': 'X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept',
    'Access-Control-Allow-Access-Control-Max-Age': '1728000',
  })
};

console.log('Try login');
this.http.post('https://news.ycombinator.com/login', payload, httpOptions)
  .pipe(
    tap(
      data => console.log(data),
      error => console.log(error)
    )
  ).subscribe(result => console.log(result));

how could I solve?

Zoe
  • 27,060
  • 21
  • 118
  • 148
Gabriele Picco
  • 457
  • 4
  • 22

3 Answers3

1

You cannot make an ajax call to a server with CORS. The browser checks the CORS policy of the server.

An Android/IOS app is not a browser it can make the call without being blocked.

If you have your own server, you can make the request to your server which in turn will make a request to Harker Ranks server's and return the response to your Angular app.

Get the page using curl request. Replace acct and pw with your credentials.

curl -L -X POST \
  https://news.ycombinator.com/login \
  -H 'Access-Control-Allow-Headers: X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'cache-control: no-cache' \
  -d 'acct=username&pw=password&goto=%20news'

Shashank Raj
  • 106
  • 1
  • 5
  • There are no other solutions without an intermediate server? – Gabriele Picco Feb 15 '19 at 11:50
  • However I also tried with curl and I can not make the call, only Postaman works for me. I do not understand what the problem could be. – Gabriele Picco Feb 15 '19 at 11:51
  • There is no other way to pass the CORS policy other than having an intermediate server. If you need a simple intermediate server you can use firebase clound functions to deploy your node sever. – Shashank Raj Feb 16 '19 at 07:24
  • The reason you were not able to get the response from https://news.ycombinator.com/login using curl is that it has a redirect. You can use -L option in curl to follow the redirects. – Shashank Raj Feb 16 '19 at 07:25
  • Yes, you're right, thanks! I will try then to host a proxy. – Gabriele Picco Feb 16 '19 at 12:37
  • I'm trying to use the Angular CLI development server proxy, unfortunately with Angular I still have not been able to make the request: https://stackoverflow.com/questions/37172928/angular-cli-server-how-to-proxy-api-requests-to-another-server – Gabriele Picco Feb 18 '19 at 15:05
0

I am facing the same issue while making a request from web domain to web API domain and resolved the same in the following way:

  1. Add the following configuration in the web api configuration file to enable HTTP request and to allow customer header : enter image description here

  2. Create an XML file with name crossdomain.xml and add this file at the root location of the web or app project. enter image description here

  3. Also, add the following configuration in the configuration file of web or app project: enter image description here

This will resolve the cross-domain issue.

Jayoti Parkash
  • 868
  • 11
  • 26
  • But the problem is that I can not change the API, they are not made by me. I only have access to the client – Gabriele Picco Feb 18 '19 at 09:26
  • If you have the API code then you can test the same on your machine. After that share the same information with your client and let them decide, what they want. – Jayoti Parkash Feb 18 '19 at 10:46
  • I honestly do not understand yours, answer. I need to access the HN APIs, but I can not change them. I only have access to the client. – Gabriele Picco Feb 18 '19 at 14:48
  • Ok. Just go through this link https://stackoverflow.com/questions/53684484/posting-to-external-api-throws-cors-but-it-works-from-postman and try in this way, It should work. – Jayoti Parkash Feb 19 '19 at 06:33
  • No, I do not have an authorization code like that question. The solution unfortunately is only using a proxy. – Gabriele Picco Feb 19 '19 at 09:13
0

The solution for CORS problems is to use a proxy, for angular, in development, you can use the Angular CLI server as a proxy (https://stackoverflow.com/questions/50021126/implementation-of-proxy-server-in -angular4-5? rq = 1).

This is my proxy.conf.json:

{
  "/hackernews/*": {
  "target":  {
      "host": "news.ycombinator.com",
      "protocol": "https:",
      "port": 443
  },
  "secure": false,
  "logLevel": "info",
  "changeOrigin": true,
  "pathRewrite": {"^/hackernews" : ""}
  }
}

Edit "start" of your package.json to look below

"start": "ng serve --proxy-config proxy.conf.json"

Unfortunately for the actual build there is no such simple solution, a proxy can be specified on the production server, depending on the server used.

Gabriele Picco
  • 457
  • 4
  • 22