Origin’s Origin Story: a Brief History of Web Content Origin

Dan Tracy
5 min readOct 18, 2019

--

This was not the article I intended to write.

I intended to write a quick-fix article about a CORS conflict that was ruining my day(s), and I began by introducing the concepts of same-origin-policy and CORS… and then it turned into this full-length article you see before you, and I hadn’t even begun to address the issue. I cover the issue here, but I think it’s nice to get an idea of what we’re working with before we start doing tweaks.

And therefore, I bring you the origin story of web content origin, and the hero that loved it.

Content Origin

The Origin of web content is at once a simple and complex thing. At its core, there are basically three elements: the page that has the data, the page that is requesting the data, and the method in which that data is transferred (the scheme, or transfer protocol).

Now, way back in 1995 when Netscape Navigator 2 was around (and incidentally the same year JavaScript came out), there was this security concept created called “same-origin-policy” that said that a script on one webpage can access data on another webpage if they both have the same origin; i.e. same URI, same host, same domain. This was created for security purposes and at the time it was a great idea; having a page that could be accessed and edited from anywhere is like keeping your jewelry box on the sidewalk for safe-keeping.

Should be fine, right?

Now, this is all fine and dandy if you’re making your own server and all the data is just on another place on your site. But things get tricky when you’re requesting data from a different server.

Fortunately, since requesting data from another server is, like, the entire purpose of the Internet these days, some cool guys named Matt Oshry, Brad Porter, and Michael Bodell saw fit to invent CORS and make everyone’s lives a lot easier.

CORS

CORS stands for Cross-Origin Resource Sharing, and as you might imagine, it allows you to get resources from different origins.

If you have some experience with web development, you probably know that your HTTP request is sent with headers (and a bunch of other stuff) that is used to give instructions to the server about what to serve up. The server-side, meanwhile (assuming it’s CORS-enabled), uses CORS to establish which origins it thinks are cool enough to read its data. When using the standard XMLHttpRequest() verbs (GET, POST, HEAD), a CORS-enabled origin is generally satisfied.

This is important because now I, on my site (site A) can use an image from site B (with permission, RIGHT GUYS?) and site B can use CORS to allow certain requests (in this case, a GET request) through.

However.

When writing your code from scratch, you aren’t always going to get these headers out of the box. Which can get confusing, because if you use a REST client like Postman, you just typed in the URI, maybe threw in an API key if you needed it, and voila, some data:

But when you use the same URI in your application, you get an error like this in your console:

This ‘preflight response’ is a little extra measure of security that the browser-side sends to the server-side, essentially saying “Hey, here’s what I’m doing. We good?” And when you are blocked by CORS policy, you kind of forgot to say “Please”.

This is a massive simplification, but to get around this, let’s head back to Postman and open the ‘Headers’ tab to learn some manners:

Here are all the pleases and thank-yous Postman sent over that maybe you did not. And maybe you sent over some bad headers that you shouldn’t have!

It’s easy to modify this in Postman, but how do you do it in your code?

Coding Around CORS

For simplicity’s sake, the request body is just an object that you can manipulate.

const data = await axios.get("https://dataiwant.com",
{ // THIS IS WHERE THE REQUEST BODY STARTS
headers: {
// your custom headers go here
}
}
)

One of the keys in this object is the ‘header’ key, and you can add whatever you like to it. Let’s add that Access-Control-Allow-Origin header (in string format, because your code is not going to like all those hyphens).

const data = await axios.get("https://dataiwant.com",
{
headers: {
"Access-Control-Allow-Origin": "*"
}
}
)

And if the server at “https://dataiwant.com” has also configured itself to allow all origins, you’re good to go.

And that’s it! Manipulating headers couldn’t be easier. The tricky part is figuring out which errors are causing problems, but for starters, I would recommend paying special attention to the Access-Control-Allow-Origin header; it’s kind of an important catchall header that often causes problems if not properly implemented.

So that, in a very small nutshell, is the story behind same-origin-policy, and CORS, the dark knight who came in to save the day. It’s also a microcosm of software itself: smart people build a thing to fix an issue, then more smart people build another things to help streamline the process of using the first thing. It’s a beautiful circle.

Epilogue

Did you inspect the error above? Of CORS you did, and you saw that Access-Control-Allow-Origin wasn’t actually my problem at all. If you’re interested in reading about that one out, check out my other article, Resolving CORS Conflicts with the ArcGIS JavaScript API.

Thanks for reading!

--

--

Dan Tracy

Software developer specializing in JavaScript/Node, React, Express, and Postgres. Other interests include GIS, data viz, and the piano. Looking for a good job!