call non-CORS REST APIs over AJAX with CORS proxy server (includes Svelte+Rollup setup)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you have used REST API is and made Ajax calls to those REST API is from JavaScript then it is very likely that you are aware of course issues or same origin policy sop issues if not then no problem I will explain what course and same religion policies are but more importantly for those who know what course and same origin policy that you have if you have faced that and if you have an API or a REST API that is not ready for course and does not expose course headers then in this video I'm going to show you how to get around that problem and still use it and then hopefully either you continue to use this approach in production as well or maybe in production you have a different way of deploying or a different place where the API is deployed so that the issue goes away on its own if it doesn't this method will still work so let's talk about what the issue is okay before that let's talk about what score's is see ors now see ors is a solution to a problem and the problem is SOP same origin policy and what is that it basically means that if you have JavaScript being served from server a then it can make a call back only to server a and not to other servers but that rule can be broken if the other server is prepared to be called and the other per server is exposed special headers that are course headers cross-origin resource sharing headers and the name of the header specifically is access - control - allow - origin as long as the origin server of JavaScript is listed in access control allow origin the rest api server will will will expose that in the access control and the origin and the browser will allow JavaScript to call such a server okay all this is very theoretical let's actually see an example all right so I have here let's see let me take you to this random joke API so I'm gonna copy paste so this is the the URL of a cell I'll make this URL available in the show notes but let me zoom in on the URL a bit yeah so it's joke API strict course HTTP joke API strict course appspot.com random joke okay so this is the URL and when you when you hit it directly in your browser it obviously responds and it's has a set up it returns a joke with a setup and a I guess setup in it and a punchline yeah that's what it does so here you have setup if you boil a clown then the punchline is do you get a laughingstock question mark so okay well the quality of the jokes as well as how funny they are is up to you to decide but any case my point is to demonstrate the course issue and the solution to it okay so now what is this is working just fine what's the issue there is no issue well if you look at the the headers and you will notice that the response does not have access control allow origin header okay now access control allow origin header is what allows cross-origin resource sharing and this will become evident when we try to call this service let's do that okay so what we will do is oh sorry I have something open let me close it okay okay I'm going to CD dev web RM minus RF course demo I was just working on that so I got rid of it okay now I'm going to create the directory course demo and in there I will go I will see D to it and then I will do a basic so make directory basic and basic is a basic demo of the issue okay all right let's open this as a project as a folder so of course demo break basic there it is it's an empty folder so I am going to write some JavaScript so that I can hit this okay so let's create a new file we will call it index dot HTML and there is the basic skeleton of an HTML page and I will call this course then [Music] course demo and we will have let's say they're going to make a call to the server so let's do that create a button Ajax wall I guess right and we will say fetch okay so this will have an ID let's give it an idea button b1 and we will yeah let's just we can have a set up in and the other thing right here so Dave ID setup this is the setup and then we have Dave ID punch line sorry punch line that's the punch line and we could put dot dot dot between those okay now we have a basic HTML page let's open this in live server so this is the live server and there you see in case you're not familiar with life server life server is the plugin for vs code that will run a small web server and serve your page using that life server okay so that's all we did I just right-click on it and say open in life server and that's what it opened it's running on 127 dot zero dot zero dot one and fifty-five hundred let me make sure that the fonts etcetera are visible okay hopefully that's readable enough okay all right so now we will write some JavaScript that will fetch the joke so let's write some script JavaScript and we will say when this button is face clicked the joke should be fetched and plugged into the setup and punchline okay so we just say document dot get element by ID and we will get the button one you can say wants to be one now I'm using some advantange JavaScript syntax I hope that's okay this is just to demonstrate the issues of course okay all right so now that's your button let's also get the other elements so there you have set up and that's set up and this is punch line and it's punch line okay now let's see the one dot now we will attach the click handler so add event listener and the name of the event is click and here's your handler and the end is going to be a function could be at lambda function or just as function either will work and we say okay when this button is clicked let's run if request and so this is the rights request and the URL as you know is this so let's copy this URL and paste it here that's your I mean you could always do this constant URL equal to all of them will walk you so we fetch the URL and when that succeeds so you have a ten and when such a thing succeeds then you want to take the response and from that response you can return the response dot JSON you are passing the response JSON and when that succeeds I hope this will work then you want to just assign that those values to something so if we have a JSON response then we want to say and here's the body you want to assign this to to these two two divs right there in your HTML so we will simply say well setup this is the deal dot inner HTML is equal to or inner text rather in a text list to that is equal to json dot setup and then similarly punch lines inner text is equal to this on that punch line so let's see if this works it won't but let's try it anyways so i save this and hopefully this would work I go to inspect I want to show you what happens in console I fetched joke and there you go most of it worked you know listening to the event the event length listener was fair was triggered but then we get this error access to fetch at and once again let me make this font bigger access to fetch at fetch API strict course appspot.com random joke from origin one 27001 5500 has been blocked by course policy no access control allow origin had at its present so this is the issue this is what is path stopping course the browser rather this is what this is wipe the browser refuses to access such a such a restful service an HTTP service so you can check that in network if you go to network and look at this and you will see that there is really no such header so the header is missing so what we are looking for is an access control not request error sorry response header there should be an access control allow region in here which is not there ok so now hopefully you understand the problem let's bring up the solution the solution is and let me show you what the solution is is something called course anywhere so of course anywhere is an NPM module so let's go to NPM j/s yes this one this is called course anywhere and the way you use it is you run your own you can run your own little proxy server locally and this proxy server will instead of hitting the the joke server directly we hit ours proxy server which in turn will hit the actual joke server and since the request is being made from our browser to our local sorry our JavaScript is being served from local host and this proxy server is also running on local host such a requester allowed and then the proxy server makes a call to the service that is running over here right and that service anyway doesn't have a problem it is not ready for course but then the course is a browser policy it's not a policy in enforce and by node.js specifically this course anywhere server okay so this is how we get around the problem so let's implement it all we have to do is copy paste and so let's get course anywhere as a as an NPM module so in order to get any particular NPM module first we have to create a package dot JSON so we can do that by saying NPM in in it - y as in take say yes to all questions so take all the defaults so we just did that and now we can install NPM install you could say - - save I guess turn is necessary and we say of course anywhere so we are downloading this this NPM module called course anyway now that we have that we can create a new file and let's call it proxy dot J s so now and we we copy this this code and paste it into proxy dot j s so what is it doing it simply loads the NPM module and using it creates a server it has originated list it requires that the the client send origin and X requested with and then it removes the cookie header and cookie - header and this is helpful because it makes your system more secure you are not sending your private cookies over to the wrong server by mistake okay so this is why the header start to be removed and then finally just prints running course anywhere on such in such host ok so let's save this once we save this remember we were getting this error let's make sure we are getting this error fetch joke Wow let's do that good now let's run this proxy is using node.js so I will say node proxy is okay so this is running and now it's running course anywhere on and my public IP so I don't want to do that let me control see kill that and I want I'll change this from 0 dot 0 dot whatever to 127 dot 0 dot so this way it is not accepting connections from anywhere and everywhere it's just accepting from my local host if you are running this on a different host on your network you might have to open it up a little okay so let's save this and let's run this again and now it's running on this for good now we have to change our code in index dot HTML instead of making that request to this URL directly we will create we make it through the proxy so let's say proxy is equal to HTTP 127 sorry flash / 127 dot 0 dot 0 dot 1 H 0 H 0 and slash this slash is important because we are going to combine these two the proxy and the URL we are combining them together so now what is going to happen is when we make a request to this URL we are not going to make it directly to this URL from our JavaScript browser JavaScript we are going to prefix with it with the proxy and now the requests the total request link is this Plus this okay and the proxy server is programmed so that it it sees the URL path as the URI path as the URL it is supposed to proxy to and just makes a request for you release the response back to you okay let's see whether this works so I saved it I reload of course and now I fetch joke oh look at this and we actually see the joke here's the setup where you call a cow with no legs ground beef is you can play with this as much as you want Hills hip hip and then hip hip array so this is the programming joke I guess and if you look at the network you will see that we made two requests the first one was made to 127 bla bla bla and then this time it does have access control all our region and in any case it doesn't need it so much because they are its from JavaScript is from localhost and the server you are calling is also localhost but any case it doesn't hurt and then this proxy server made a request to jokes API on our behalf which is over here and it works just fine great so this is the quick workaround on what to do when a service doesn't allow you to call it directly from your JavaScript but this is only part of the solution this is very clunky and I am running this is not how you are going to do anything in the real world in real world you you won't be serving your index dot HTML with live server and in real world you don't want to run your proxy server like this from command line like this so let's kill this we could improve on this by going to package dot JSON and we add a script and we will call it proxy script and now the proxy script will simply run node then proxy dot yes it's a very small improvement but maybe it it helps and now in NPM scripts we can just click proxy and now it's running in its own little terminal or you know its own shell I guess and we have our own shell I am quite ready and available so this helps a little bit it doesn't change much but yeah yeah things are working as they should be what do you give to a lemon in need lemonade ha ha ok very appropriate lemon of a joke let's but this is again still not absolutely the way we do things so let's now replace this very basic project with something that we would probably use in real life since you as you know I love swelled hence the big swells logo and I love roll-up or hence the mention of a roll-up proxy server so we will convert this to a swirled application and we won't convert it with the started from scratch so let's kill this and let's see the dot dot and we will we will copy the swelled application starter-kit started a project but as we always do we say NP x deck it swelled GS / roll-up now if you are not familiar with swelled and roll up don't worry these things are still applicable to what you are going to do you could be using webpack or you could be using other other task runners like gulp this knowledge will still be applicable so let's do that and we will call this swell ro course let's call it this control of course cross-origin resource sharing again okay so the what happened here oh sorry I made a mistake it should the this path is not swell just roll up it swell GS / template my bad okay now let's open that project instead of this one so that it is swell trial of course this is a basic swelled template in order to run it we have to first do npm install so let's do npm install okay i hope npm install' is already done maybe it is let's find out I don't think I mean it might might not work let's see yeah I did what I would right click and say run install so it is doing npm install for us and so this project is obviously a starter project it already has the roll up config it has package.json it even has some basic source etc so we will see how this goes all right so this is finished let's keep going let's okay so let's now run this project where yeah there is okay so before we even do anything let's just fix the app dot in SRC let's fix main dot JSON we don't need the the default props so let's get rid of that and in app dot yes you don't need any of this stuff oh yeah let's call this course demo okay and we'll say with swell and roll up of course I have I cannot use end like that as I am P ampersand like that okay and then we can put two divs to do for setup and Dave for but since this is swell and not plain JavaScript and plain HTML you can do things in a better way let's see Dave and this is setup and if this is punch line and put dot dot no need for IDs because we are going to use bind this okay and we will give this so bind this gives you a direct reference to this Dom element setup and similarly bind this and this will be punch once you do that oops misspelled punch line once you do that you can oh let's get rid of this name let setup and punch line these are variables declared now okay so there's okay so now we can once they're bound let's create a button button and this will be fetch joke button and I am going to now again this is well not plain HTML in JavaScript so we use on click on on : click and then give it a method it will call it function call back called face well we cannot call it a face because that's the name of the method we are about used so let's just call it fetch joke and let's create it so function fetch joke and we will use the same URL which is right here I'm gonna copy it so this is Const you are L equal to double quotes this and we say fetch this URL and this time instead of using dot then let's use the async await syntax so Const response is equal to a wait as soon as you start using await the system will start complaining pretty soon that you cannot use a wait this is not an asynchronous function so let's make it in asynchronous function once you make this an asynchronous function however it is okay then let's say Const JSON is equal to again this is also asynchronous oh yes your say oh wait response dot JSON okay and now you have a JSON the JSON is this JSON and you have parsed it so now let's assign it all we have to do ooh sorry what am i doing I don't need bind this this is the wrong way to do it the right way is I can simply set these variables this will be set up and this will be punchline yeah sorry yeah I didn't mean to make those variables references to Dom elements it's much easier to simply say setup is equal to json dot setup and punchline is also json dot punchline and once you do that and we can we can even give it some starting value set up is set up like this because that's what you want to see in the beginning and punch line is punch line okay so once you save this let's see if this works now of course this is the old live server we are no longer hitting this live server we need to hit the so at this point is everything compiling first of all let's see it should be compiling let's let's just restart the dev server hopefully if it you start the dev server good and it compiles so let's hit the localhost 500 in here copy and paste that in here this is my roll-up server running okay course demo of its well controllable it has a little bit but too much style so that's cool it's centered also that's fine we don't care let's now make the request ha error same old error as before because we did not use any kind of proxy server okay so this is the key thing you wanted to demonstrates the response headers that are there is no access control allow Allegiant okay and that's the reason why in the console it says you know can't access you don't have X you don't have course and cross-origin resource sharing okay all right so obviously we know how to fix it now using course anywhere let's do that so let's go into a shell and NPM install mine I'm gonna save or save dev if you want but course any where now that we have that we want to run that server now this is where roll-up comes in instead of running the server in parallel there are many ways to do that we could copy that proxy dot Jas over here and you know as you know here's the here's the code and this is the code you could copy this and run it independently but that's that's not what we want to do we want to do it in a way that roll-up would that is friendly to roll up so here is roll up dot config dot GS roll-up is already doing something very similar we just have to leverage that you see roll-up is running a web server and it says when I'm not in production run this web server we and this that web server is what is serving the app from local O's 5,000 we could just use that same approach not the same server but the same approach so I'm going to copy and paste and duplicate that okay and I will keep this started false and then even later started true and it what what is happening is we are running we are we are adding a little tiny little custom roll-up plug-in and that's how the web server is running similarly we will also do the same thing of course we cannot call this server you have to call it something else we'll call it proxy and it uses this the bundles sorry the roll-up plugins they have this thing a callback called right bundle and that is called when it is ready to it's one of the callbacks okay it's ready to write the output and we kind of leverage that to do what we want which is in this case not running up a web server but running a proxy server and that's where we copy and paste this code let's copy this code and we will paste it exactly here let's reformat this a little and as I said since our JavaScript is from localhost let's just change this to localhost okay save it so now this is going to run course anywhere on localhost 8080 so we go back first of all we we restart our dev server so that hopefully we will have yeah so waiting for changes hopefully our something is running on a port 8080 maybe let's find out if it is we can find that out easily by running net stat - NT a crap 8080 it's not running on poor oh yes of course it's not running because we never started it we never called this proxy function sorry my bad so I'm going to take this if we are not in production run the web server we are just duplicated and we'll say we are not in production to run the proxy server same exact thing okay so if we now restart the dev server hopefully it will run correctly this time there you are you see localhost:8080 it was saying and I can prove that by running that netstat and grep 8080 and as you can see someone is listening on port 8080 that's our proxy server ok now that everything is in place we just have to change the code so let's change the code we will go to app dot svelte and [Music] instead of making the request directly to URL we will add a proxy server so Const proxy is equal to HTTP localhost 8080 slash and then we make the request we add the proxy right in front of the URL ok oh sorry semicolon yeah save this and now let's see what happens fetch joke and there you go you got a joke what's the best time to go to the dentist and the time is 2:30 tooth hurty or 2:30 ok all these these jokes are a mixed bag some of them are good some of them are not so good but hey it's a free api and the point of this is not to laugh but to learn ok and we are learning about course and we are learning how to run our own little proxy server called course anywhere to get around the course issues or lack of course headers great so this is this is very good I mean we could improve this just a little bit there is something we could we could do the problem is if this code ends up in production then now it is always expecting yeah it's expecting this to to be there the proxy server to always be there and maybe in production you don't want to do that then what ok so we have a solution the solution is we whenever we are in production we could detect that and we could not only not run the proxy server which of course won't run anyway I wrote up that config it doesn't run the proxy server if we are in production right but it would also remove this proxy server how do we do that well fortunately there is a plug-in a rollup plugin called replace so let's let me just show you roll-up plug-in replace so this is the replace plug-in if you look at this plug-in all they're saying oh yeah this is the new place for Ola plug into place so let's click on that and one of them is replace plug-in there is a replace plug-in there it is click on it and it shows you how to use it so this role a plug-in called replace oh by the way I'm I made a little mistake I forgot to import the this course proxy oh sorry it is important here sorry never mind so yes replace plug-in so we will just import it like this and then in the chain of plugins we will add replace into the chain let me just show you how let's first of all let's add a replace to our project so there it is little copy this okay let's kill this NPM install - - save dev or say maybe yeah yeah it's at the development time so yes save there oh it's needed only at Build time right so roll up plugin replace and we install it so the idea is that we shouldn't have this proxy server even in the code anywhere it should never be expected it should be just compiled out and that can be done once we have added a place we can go to roll up and say hey import this replaced plug-in and roll up config and then right in the very beginning before you even do swelled call replace plug-in and what are we replacing so first of all you are to give it an object and in that object you have keys and values keys are what you are replacing and value is what you are replacing it with and in this we will instead of having localhost:8080 we can say hey replace that with I guess nothing or you could yeah there are many ways to do this but we will call this will replace it and say we'll call it course proxy URL let's call it this mhm and now we will say hey whenever you see course proxy URL replace it now if you are in production then replace it with nothing if you are not in production which means there then replace it with HTTP that's that local host 8080 slash so this is a very simple replacement save this come back here and then there is one more thing you need to do remember this course proxy URL will be replaced either with localhost 8080 or with a blank string so we can simply well we don't even have to do anything at this point this will be blank and we in which case you are adding blank in front of URL works just fine right let's rerun our dev now if this is not working at all then we will get a big error thing you are trying to hit a URL called course underscore proxy underscore URL so let's find out hopefully that doesn't happen okay I reload and I make a request and it works so this is definitely working and because it's the when the bundle was generated this particular token was replaced with localhost:8080 now if I just change this to production and which means we I just say hey we are in production let's say so only for our testing if I say instead of I just reverse this condition and which is going to reverse the condition so that I can test this alright so here we are I do have to restart the roll-up server okay so now we are not replacing okay so I rely here on the role approach so the proxy server is still running but we will not be since we are not doing replacement or we are doing a replacement of the wrong kind we are making it blank it will try to hit the server directly and it will fail to do that it will get the course error there you go access control it's directly hitting the server a joke API and that should hopefully show you two very useful NPM packages one is the course proxy and that is the main focus of this video and then a second which one is a rollup plug-in and now of course in order to make this correct I have to remove this production ok so now once I fix that I don't know okay I do have to restart roll-up is still using the old old configuration restart and I reload and now let's fetch a joke and there you go what are the ten types of people in this world those who understand binary and those who don't haha what are the ten types in binary this would be two oh nice so I hope you guys understand now what what same-origin policy is what course cross-origin resource sharing is why you might have a problem with some REST API is that are not course compliant how to get around that problem with with course anywhere NPM module how to do this in a in a very raw basic manner as well as in a more sophisticated manner with roll-up and writing a little roll-up plug-in that runs your proxy server I hope you learned something I will see you in the next video
Info
Channel: SpinSpire
Views: 3,133
Rating: 4.7837839 out of 5
Keywords: Svlete, SvelteJS, JavaScript, ReactJS, web, svelte, sveltejs, javascript, web development, reactjs, nodejs, html, rollup, npm, ajax, CORS, cors-anywhere, same-origin-policy, access-control-allow-origin
Id: EHikjXtRp_k
Channel Id: undefined
Length: 44min 41sec (2681 seconds)
Published: Tue May 05 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.