Skip to content

Commit 97fae69

Browse files
kenfdevalexellis
authored andcommitted
Add reference about CORS and local development with Web Apps
This is still a draft. Signed-off-by: Ken Fukuyama <[email protected]>
1 parent 41f9aaa commit 97fae69

File tree

6 files changed

+53
-15
lines changed

6 files changed

+53
-15
lines changed

docs/images/cors/cors1.png

21.2 KB
Loading

docs/images/cors/cors2.png

26.2 KB
Loading

docs/images/cors/proxy1.png

22.5 KB
Loading

docs/images/cors/proxy2.png

27.5 KB
Loading

docs/reference/cors.md

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,46 @@ If you have seen the error message above in your web application, this is the co
66

77
## Understanding the Same-origin policy
88

9-
First of all, you need to know that browsers have a policy called the **Same-origin policy** for security reasons. Under this policy, a script inside a web page can access other web page's data only if they both have the same **origin**. An **origin** consists of URI scheme, host name, and port number. This means, a script inside `http://example.com` can only access data within the same origin such as `http://example.com/users`. Trying to access data in other origins such as `http://sample.com` will lead to a violation error.
10-
11-
12-
13-
14-
15-
You don't want arbitrary scripts sending to or retrieving data from malicious web sites so the **Same-origin policy** plays a very important role in order to protect you from these threats.
9+
First of all, you need to know that browsers have a policy called the **Same-origin policy** for security reasons. Under this policy, a script inside a web page can access other web page's data only if they both have the same **origin**. An **origin** consists of URI scheme, host name, and port number. This means, a script inside `http://example.com` can only access data within the same origin such as `http://example.com/users`. Trying to access data in other origins such as `http://sample.com/users` will lead to a violation error. You don't want arbitrary scripts sending to or retrieving data from malicious web sites so the **Same-origin policy** plays a very important role in order to protect you from these threats.
1610

1711
## Problems in Developing Web Applications Locally
1812

19-
There are situations where the **Same-origin policy** gets in the way. What if you wanted to develop a Single Page Application locally and access data via OpenFaaS functions? Often, developers get stuck with an error telling you that you don't have a `Access-Control-Allow-Origin` header present. This is because your local web server and the OpenFaaS gateway have **different origins** as illustrated below.
13+
Despite the pros, there are situations where the **Same-origin policy** gets in the way. What if you wanted to develop a Single Page Application locally and access data via OpenFaaS functions? Often, developers get stuck with an error telling you that you don't have a `Access-Control-Allow-Origin` header present. This is because your local web server and the OpenFaaS gateway have **different origins** as illustrated below.
2014

15+
<p align="center">
16+
<img src="/images/cors/cors1.png">
17+
</p>
2118

2219
## Using Reverse Proxies as a Workaround
2320

2421
Mainly there are two ways to deal with this problem. Either set a CORS header (which is not covered in this page) or make the browser **think** it is talking to the same origin using reverse proxies. If you place a reverse proxy inside or in front of your web server, you can route specific requests to specific targets. For example, you can route all ajax requests in your web application which start with `/api` to the OpenFaaS gateway by proxying it from the web server as illustrated below.
2522

23+
<p align="center">
24+
<img src="/images/cors/proxy1.png">
25+
</p>
2626

2727
This way, the request from the browser doesn't violate the **Same-origin policy** and under the hood, would be proxied to the OpenFaaS gateway.
2828

2929
## An Example with a Vue.js + Webpack Application
3030

31-
Let's look at a very minimal Vue.js Single Page application setup with webpack to actually see how it works. A developer will run `npm run dev` to spin up a local dev server via webpack. Suppose this was served on `http://localhost:8081`. By default, the OpenFaaS gateway will be exposed on `http://localhost:8080`. This means the local dev server and the OpenFaaS gateway have **different origins**. Therefore, if the Vue.js application requests data from the OpenFaaS gateway (`http://localhost:8080`), it will fail because it violates the **Same-origin policy**.
31+
Let's look at a very minimal Vue.js Single Page application setup with webpack to actually see how it works. Typically, a web developer will run `npm run dev` to spin up a local webpack dev server. Suppose this was served on `http://localhost:8081`. By default, the OpenFaaS gateway will be exposed on `http://localhost:8080` which means the local dev server and the OpenFaaS gateway have **different origins**. Therefore, if the Vue.js application requests data from the OpenFaaS gateway (`http://localhost:8080`), it will fail because it violates the **Same-origin policy**. The following diagram shows the relation.
32+
33+
<p align="center">
34+
<img src="/images/cors/cors2.png">
35+
</p>
3236

33-
The code below is accessing an `echo` function from the Vue.js application:
37+
Here's a quick view of the code trying to call the `echo` function from the Vue.js application:
3438

3539
```js
36-
// url to the echo function
40+
// URL to the echo function
3741
const url = 'http://localhost:8080/function/echo';
3842

39-
// sample payload
43+
// Sample payload
4044
const data = {
4145
test: 'test'
4246
};
4347

44-
// ajax request
48+
// AJAX request
4549
fetch(url, {
4650
body: JSON.stringify(data),
4751
method: 'POST'
@@ -50,6 +54,39 @@ fetch(url, {
5054

5155
and ends up with the following error:
5256

57+
> Failed to load http://localhost:8080/function/echo: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
58+
59+
In order to solve this problem, we'll need a reverse proxy to proxy the request from the webpack dev server to the OpenFaas gateway. Luckily, the webpack dev server has a built-in feature for this by taking advantage of the [devServer.proxy](https://webpack.js.org/configuration/dev-server/#devserver-proxy) feature. You can simply write a definition as follows in your webpack configuration:
60+
61+
```js
62+
proxy: {
63+
'/function': 'http://localhost:8080'
64+
}
5365
```
54-
Failed to load http://localhost:8080/function/echo: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
55-
```
66+
67+
With this, all your requests starting with `/function` will be proxied to the gateway (http://localhost:8080) which is exactly the behavior we want. The following diagram shows how the data flows.
68+
69+
<p align="center">
70+
<img src="/images/cors/proxy2.png">
71+
</p>
72+
73+
Now that the requests would be proxied, the previous code will look like this:
74+
75+
```js
76+
// URL to the echo function.
77+
// Note that the origin isn't needed since we request to the same server.
78+
const url = '/function/echo';
79+
80+
// Sample payload
81+
const data = {
82+
test: 'test'
83+
};
84+
85+
// AJAX request
86+
fetch(url, {
87+
body: JSON.stringify(data),
88+
method: 'POST'
89+
}).then(res => res.json())
90+
```
91+
92+
Which will end as a successful request.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pages:
124124
- Reference:
125125
- Secrets: ./reference/secrets.md
126126
- Auth: ./reference/authentication.md
127+
- CORS: ./reference/cors.md
127128
- Design & Architecture:
128129
- Gateway: ./architecture/gateway.md
129130
- Watchdog: ./architecture/watchdog.md

0 commit comments

Comments
 (0)