2

Thanks for so many fast response.
I used NodeJS(v4.3.2) and ExpressJs(v4.x) to build up website.
I used a lot AJAX and all AJAX url point to one static IP(AWS Server itself).
Because I would deploy to several servers, I don't want to change AJAX url separately. My idea is when I run "node bin/www" command line, Can I change it to "node bin/www 50.50.50.50(my AWS address)" and I can set all AJAX url to the right IP?
Is it possible or other alternative solustion?
Thanks

鄭元傑
  • 1,417
  • 1
  • 15
  • 30
  • This is a CORS issue: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS. You have to set headers on your server response to authorise the client to communicate via Ajax – cl3m Mar 03 '16 at 08:39
  • Please see ["Should questions include “tags” in their titles?"](http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), where the consensus is "no, they should not"! –  Mar 03 '16 at 08:50
  • I would suggest remove `http://127.0.0.1:3000` from all your Ajax request urls. So change `http://127.0.0.1:3000/blablabla` to `/blablabla`. That will make it relative to the domain and port, so that if you are accessing the website from your own local server it will request `http://127.0.0.1:3000/blablabla`, but if you access it from some domain name or other IP, it will use that (IE. http://50.50.50.50/blablabla ) – Paul Mar 03 '16 at 08:54
  • See also http://stackoverflow.com/questions/4870328/how-to-read-environment-variable-in-node-js and http://stackoverflow.com/questions/22312671/node-js-setting-environment-variables and http://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth ... – CupawnTae Mar 03 '16 at 08:55

2 Answers2

2

Your issue is related to CORS : basically, you cannot access a domain http://www.example1.com from http://www.example2.com via Ajax if http://www.example1.com does not explicitly allows it in the response.

This is a "security" feature on most modern browsers. You won't encounter this problem using command line such as curl or chrome extension Postman.

To fix this, make sure the domain requesting the data (http://www.example2.com) is allowed in the Access-Control-Allow-Origin header in your server's response, as well as the http verb (GET, POST, PUT... or * for every http methods).

It all comes down to add the two following headers to the http://www.example1.com server's response :

Access-Control-Allow-Origin: http://www.example2.com
Access-Control-Allow-Methods: *

Edit

Following @Paulpro's comment, you have to rebase all your urls so that they reach your server's IP instead of your localhost server.

cl3m
  • 2,791
  • 19
  • 21
  • Thanks for fast answer! But I have one question : you mentioned "This is a "security" feature on most modern browsers." If I set up like you say , would this cause web security issue? Or why this is security feature ? – 鄭元傑 Mar 03 '16 at 08:48
  • This feature is a security mechanism for isolating potentially malicious documents. You can read more about the Same Origin Policy here: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy Please see the edit, if you want to secure your API, you should specify only domains that are making calls to your API instead of `*` – cl3m Mar 03 '16 at 08:51
  • 1
    This seems like entirely the wrong solution. If the requests are going to `127.0.0.1:3000` the website will only work for users that happen to be running a local copy of it on their own computer (IE. it will work for the OP but no one else). He doesn't need CORS, just needs to change all the ajax requests to be domain relative (or use a config file and make the domain for them configurable). – Paul Mar 03 '16 at 08:52
  • This may be a red herring - are you serving all your pages and AJAX requests from the same server? If so, CORS doesn't apply... Yeah, what @Paulpro said :) – CupawnTae Mar 03 '16 at 08:53
  • I see. I made the big mistake. @ Paulpro : you mentioned "use a config file and make the domain for them configurable" How can I do that to set up all AJAX? AJAX call exist in many files , how to set up all together in express? – 鄭元傑 Mar 03 '16 at 08:56
  • @Paupro is right, you have to rebase all your URLs. You could create a function that will returns the correct domain for every route, base on a config setting – cl3m Mar 03 '16 at 08:59
  • Thanks both of you. I will try to do that. Thanks :) – 鄭元傑 Mar 03 '16 at 09:02
0

I fix this problem.
First, in bin/www
append these code to retrieve URL for command line and store into json file.

function setUpURL(){
  var myURL = process.argv[2];
  console.log('myURL: ', myURL);
  var outputFilename = 'public/myURL.json';
  var myData = {
    port:myURL
  }

  fs.writeFile(outputFilename, JSON.stringify(myData, null, 4), function(err) {
      if(err) {
        console.log(err);
      } else {
        console.log("JSON saved to " + outputFilename);
      }
  }); 
};  

Then in each JS containing ajax add these code in the head of JS file (it need to load before ajax)

var myURL;
$.getJSON("myURL.json", function(json) {
    myURL = json.port.toString();
    console.log(myURL);
});

new ajax format

$.ajax({
    type: "POST",
    url: myURL + "/forgetPwd",
    data: sendData,
    success: function(data){
            window.location.replace(myURL);
        },
    error: function(data){
        }
});

Finally, you can run server

node bin/www your_aws_ip

It works for me now. Hope these will help you guys.
By the way, you should be careful about the path of myURL.json.

鄭元傑
  • 1,417
  • 1
  • 15
  • 30