1

I've created an AngularJS app which connects to a NodeJS server which uploads a file using ngUpload directive for AngularJS.

The issue is that upon returned data from the server, the client is blocked

Blocked a frame with origin "http://localhost" from accessing a frame with origin "http://localhost:3000". Protocols, domains, and ports must match. ng-upload.min.js:14
Uncaught TypeError: Cannot read property 'body' of undefined 

The AngularJS is running on localhost while NodeJS is running on localhost with port 3000 so the calls are cross domain (tried changing to port 80, but didn't work)

This is the form code on the client side:

    <form enctype="multipart/form-data" method="POST" action="http://localhost:3000/upload" name="iconForm" id="thumbnail_form" ng-upload>
        <div class="submitFormRow fileUpload">
            <span class="btn btn-warning uploadBtn" style="z-index: 99;">Upload resume</span>
                 <input type="file" class="input" name="file" tabindex="-1" size="12" id="file" style="z-index: 999;filter:alpha(opacity=0);">
                 <input type="hidden" value="{{PositionId}}" id="positionid" name="positionid"/>
                 <input type="hidden" value="{{user_fullName}}" id="fullname" name="fullname"/>
                 <input type="hidden" value="{{user_email}}" id="email" name="email"/>
            <div class="clear"></div>
        </div>
        <div class="submitFormRow submitBtn">
            <input type="submit" upload-submit="bar(content)" class="btn btn-danger" value="Submit"/>
        </div>
            <div>{{uploadResponse}}</div>
    </form>

This is the code on the NodeJS server:

app.post('/upload', function (req, res) {
setTimeout(
    function () {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
        res.header("Access-Control-Allow-Methods", "GET, PUT, POST");

        //res.type('application/json');
        var positionId = req.body.positionid ? req.body.positionid : "-1";
        var fullName = req.body.fullname ? req.body.fullname : "John Doe";
        var email = req.body.email ? req.body.email : "default@default.com";
        if (req.files.length == 0 || req.files.file.size == 0)
            res.send({"success":false, message: "No File was uploaded", data:""});
        else {
            var fileType = req.files.file.name.split(".").pop();
            if(!checkFileType(fileType)){
                res.send({"success":false, message: "Invalid file type", data:""});
            }
            else {
                var file = req.files.file;
                fs.readFile(req.files.file.path,function(err,data){
                    var newPath = __dirname + "/uploads/user_" + new Date().getTime() + "_for_position_" + positionId +"." + fileType;
                    fs.writeFile(newPath, data, function (err) {
                        if(err){
                            res.send({"success":false, message: "file wasn't saved", data:""});
                        }
                        else {
                            var dbSaveCallback = function(err,result){
                                if(result){
                                    res.send({"success":true, message: "file saved", data:newPath});
                                }
                                else {
                                    res.send({"success":false, message: "file wasn't saved", data:""});
                                }
                            };
                            saveApplicantToDatabase(positionId,fullName,email,newPath,dbSaveCallback);

                        }
                    });
                });
            }
        }
    },
    (req.param('delay', 'yes') == 'yes') ? 2000 : -1
);
});

The server returns a jsonp result with data inside it, but inside ngupload.min, it's being blocked and I can't use it.

How do I solve this issue ?

Alon
  • 3,734
  • 10
  • 45
  • 64

1 Answers1

0

You could use CORS if your browser supports it. Since you want to post data you can't send it as JSONP (which only supports GET requests), but there are some other workarounds you could use instead.

Community
  • 1
  • 1
Alexander
  • 191
  • 5
  • I've tried to do what is written here http://williamjohnbert.com/2013/06/allow-cors-with-localhost-in-chrome/ but it didn't work – Alon Aug 19 '13 at 11:28
  • Could you update your question to reflect the changes you've made to the server-side code? – Alexander Aug 19 '13 at 11:45
  • updated, but on the client side I still get the blocked problem – Alon Aug 19 '13 at 11:47
  • Try using the code as it is used in that blog post, i.e. send the headers within an `app.all("/upload", function(req, res, next) {...` with `return next();` at the end and place it above your current function. – Alexander Aug 19 '13 at 11:53
  • I can see the headers sent back, but it doesn't affect anything – Alon Aug 19 '13 at 11:54
  • Would it be possible for you to serve the AngularJS page from the NodeJS server instead? That would eliminate the origin problem all together. Otherwise I would suggest trying out the various workarounds such as using `document.domain` or `window.postMessage`. – Alexander Aug 19 '13 at 12:05
  • will this help ? http://arguments.callee.info/2010/04/20/running-apache-and-node-js-together/ If I will run both , will it solve the cross domain issue? – Alon Aug 19 '13 at 12:09
  • I would still recommend serving the AngularJS pages through Node to begin with, but that could definitely work as an intermediate solution and it's worth trying out. – Alexander Aug 19 '13 at 12:14
  • I have no idea on how to implement the htaccess thingy, can you guide ? in the easyphp/home folder there is that file, is it that ? and what should be written inside it? – Alon Aug 19 '13 at 12:25
  • .htaccess files are just a way to make per-directory configurations to your Apache server. Just create one in the root directory of your website (use the one in your /easyphp/home folder if that's your document root) and paste the code inside it. – Alexander Aug 19 '13 at 12:29
  • the root is easyphp/www/myproject – Alon Aug 19 '13 at 12:31
  • Create the .htaccess file there then. – Alexander Aug 19 '13 at 12:33