6

1

Im trying to make a http request from my frontend deployment/pods (Angular 7 app running inside NGINX) to my backend service (NET Core WEB API).

The URL, as indicated in the diagram, is http://k8s-demo-api:8080/api/data.

//environment.prod.ts in Angular App

export const environment = {
  production: true,
  api_url: "http://k8s-demo-api:8080/api"
};

I have CORS enabled in my API:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using K8SDockerCoreWebApi.Contexts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace K8SDockerCoreWebApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.Add(new ServiceDescriptor(typeof(K8SDemoContext), new K8SDemoContext(Configuration.GetConnectionString("DefaultConnection"))));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseCors( options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
            app.UseMvc();
        }
    }
}

So here come the issue, when I make the request I get the following console error on the Angular side:

2

If there are any issues with the image above the error basically reads:

Access to XMLHttpRequest at 'k8s-demo-api:8080/api/data' from origin 'http://192.168.99.100:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

Points to note:

  • All the other services within the cluster can communicate fine (i.e. WEB API with MySQL using the same approach)
  • These two containers can speak to each other when I run them locally
  • Both of these services run 100% when I access them individually

I'm thinking of implementing an ingress on the API, but my understanding of what that will accomplish is limited.

Any help will be appreciated. Thanks.

EDIT

I am using the following headers as part of my Angular request:

headers: new HttpHeaders({
  'Content-Type': 'application/json',
  'X-Requested-With': 'XMLHttpRequest',
  'Access-Control-Allow-Origin' : '*'
})
Barend
  • 326
  • 2
  • 13
  • 1
    That's an error in your browser, right? So this is a CORS issue between your browser and a service. – Oliver Charlesworth May 11 '19 at 21:25
  • @OliverCharlesworth that is the error in the browser yes. Any suggestions how I can get around it ? – Barend May 11 '19 at 21:31
  • @Barend I think you need to setup your web.config file.IIS probably reject your request. These answers always solves my problem. https://stackoverflow.com/questions/12458444/enabling-cross-origin-resource-sharing-on-iis7 – seyid yagmur May 11 '19 at 23:41
  • @seyidyagmur the OP already said he has done that. – geoidesic May 12 '19 at 11:50
  • 2
    Don't know why this question was down-voted. It's a good question and it's well-formatted. The only thing I would say is don't paste an image of your browser error, paste the text. Image is not legible. – geoidesic May 12 '19 at 11:51
  • I have this same issue. It seems to me that CORS is disabled by default in Kubernetes. I found some info on Google that suggests one way around this is to use Ingress – but learning how to configure ingress is a rabbit hole all of it's own. So it would be good to know how to enable CORS without having to use Ingress. – geoidesic May 12 '19 at 11:53

1 Answers1

6

While looking simple at the first look there are many ways to solve your issues. First some background on CORS: The browser automatically adds the X-Requested-With header, no need to add it in your Angular request. The browser will look for Access-Control-Allow-Origin in the response headers - otherwise you could tell the browser to trust anything, exactly what CORS prevents. (The server side has to decide if requests are allowed) So, if you want to have CORS enabled, you need to configure that in your asp.net application, which you did

        app.UseCors( options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

But you don't need CORS - your setup is carefully constructed to avoid the need: CORS will only become active when your make a cross-origin request. You configured the nginx reverse proxy in that way, that you can request the API from the same origin, where you loaded the Angular app.

The reason this is not working, is that your browser is unable to connect to the internal kubernetes hostname k8s-demo-api since that is an internal name in the kubernetes cluster.

I assume that you added a hostPort to the container of your frontend pod and that nginx is running on port 4200 serving the Angular app on the root path and the reverse proxy path is /api.

Easiest solution, given that the rest of your setup is working: Change the URL for the API to use the created reverse proxy path

 api_url: "http://192.168.99.100:4200/api"

From the screenshot it looks like you are trying to request the api without a proper protocol (http:// in this case), make sure the Angular HttpClient is configured correctly.

Thomas
  • 11,272
  • 2
  • 24
  • 40
  • 2
    The problem with doing this is next time you update, the ip changes. Ingress controller will be the way to go. – Mukus Dec 01 '21 at 09:23