The way that Karma works is that it spins up it's own web server on a pre-configured port, found in the karma.config.js file in the root of your Angular project.
reporters: ["progress", "kjhtml"],
port: 9876, <--------------
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ["Chrome"],
singleRun: false,
When we type in ng test we see our test in chrome start as shown here:
So far so good, except for one thing. Your component's outbound requests are being sent to the Karma port (9876) instead of your regular back-end port (8180). You see nothing but 404's being returned because Karma has no endpoint listeners. The "real" listeners are running from a different server on port 8180.
How do we redirect these requests?
Karma Proxy Configuration
The Karma.config.js file has a section named proxies. It's here that we will configure what amounts to a port redirect. Let's take a look at that configuration.
// Three examples of different URL paths being redirected to port 8180
proxies: {
"/Admin/Credential": "http://localhost:8180",
"/Person": "http://localhost:8180",
"/Process/Queue/Status": "http://localhost:8180",
},
Notice that all right hand side values contain the redirected port in the form of http://localhost:8180
The Rules:
1) Each proxy configuration has two parts: 1) The left side, to match the outbound path patterns and 2) The right side which is the "redirection". It includes the Schema, port but not the path. This is because the proxy redirects to the same path.
2) The left side path patterns do not include the schema or ports and must include the "/" as the first character in matching the path of the URL.
3) You still need to configure CORS support on the back-end because the outbound requests look like this:
What's odd about this, is that the outbound URL is still sent using the Karma port! However, the request headers now contain, Host, Referer, and Sec-Fetch data. It looks like nothing has changed. Right?
Indeed, if your back-end doesn't allows CORS the, request above will not work.
Backend CORS Configuration in ASP.NET Core
Add this in services section:
And this in the Configure section:
This allows the backend to receive and service the requests.
Karma Proxy Configuration Internals
When we want to "really" understand things we have to keep dropping down to the layer which confirms reality. In this case we ran a Network Trace to actually see what's happening a the network layer.
Notice that there is never a 8080 port in the conversation? This agrees with what the browser's network information showed us. We do see our Karma port (9876). What's interesting is the port 63269, this is something Karma decides to open; which originates the outbound call GET /Administration/Service (not to 8180) but to 9876. We next see the ACK to this request followed by the response of 9876 to this "other port". Indeed this is what we see in the Chrome network tab as the response, if we click the preview tab. The data just "magically" comes back to the Karma socket. The Karma port is delivering the data to 63269! It's all mirrors and is probably the implementation of CORS protocol.
In a future article we'll take a more in-depth looks at CORS.
JWP2020
Top comments (0)