0

I have a Node.js web app that I'm running on a Heroku server. I have an AJAX request in my javascript that sends a GET request to a PHP file on the server. That request is working fine, in fact, it works perfectly if I run it without any Node.js, and just a PHP web app, so I'm wondering what changes when I start with an index.js file, and node, instead of an index.php file and apache. For the sake of trying to figure this out, I have set the entire root directory as a public folder.

My index.js file is as follows:

var path = require('path');
var express = require('express');
var app = express();
var router = express.Router();
var phpExpress = require('php-express')({
    binPath: 'php'
});
var bodyParser = require('body-parser');
app.use(bodyParser.json());

app.set('port', (process.env.PORT || 5000));

app.use('/', express.static(__dirname));

app.set('views', path.join(__dirname, '/views'));
app.engine('php', phpExpress.engine);
app.set('view engine', 'php');

app.all(/.+\.php$/, phpExpress.router);

// Homepage (THIS IS NOT WHAT ISN'T WORKING)
router.get('/', function(req, res, next){
    res.render('index.php');
});
app.use('/', router);

app.use(function (req, res, next) {
    res.status(404).send("Sorry can't find that!")
});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});

In my browser javascript I have a simple GET request like this:

let xhttp = new XMLHttpRequest();
// THIS RETURNS THE ENTIRE CONTENTS OF THE PHP FILE, IT IS NOT PROCESSED
xhttp.open('GET', 'folder/file.php?name=' + $name, true);
xhttp.send();

Which works perfectly if I don't use Node.js, but returns the contents of the file.php, using Node.js. Chrome tries to download the file.

I've never used PHP before, and I've only made a node.js webapp that was exclusively JS on the server, so it's very possible my index.js isn't configured appropriately for PHP and/or I'm missing some other important files in my root directory; let me know if there is more information I can include.

What's going on that causes this? Any help or advice would be much appreciated, thanks :)

Addition:

I'm adding this example to be more clear:

I have a php file on my server, file.php

<?php
    $name = $_GET['name'];
    echo $name;
?>

I have a js file to run in browser, main.js

let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
    if (this.readyState === 4 && this.status === 200) {
        console.log(this.responseText);
    }
}
xhttp.open('GET', 'folder/file.php?name=jerry', true);
xhttp.send();

When that js file runs, it logs:

<?php
    $name = $_GET['name'];
    echo $name;
?>

But I'd like it to log:

jerry
Community
  • 1
  • 1
jeremye
  • 1,368
  • 9
  • 19

2 Answers2

1

You Should Put your php folders & files inside the views folder because you set template engine path to /views that means you should have your file.php under /views/folder/file.php

This is my app structure

├── app.js
├── package.json
└── views
    └── folder
        └── file.php

and my app.js is

var path = require('path');
var express = require('express');
var app = express();
var router = express.Router();
var phpExpress = require('php-express')({
    binPath: 'php'
});
var bodyParser = require('body-parser');
app.use(bodyParser.json());

app.set('port', (process.env.PORT || 5000));

app.use('/', express.static(__dirname));

app.set('views', path.join(__dirname, '/views'));
app.engine('php', phpExpress.engine);
app.set('view engine', 'php');

app.all(/.+\.php$/, phpExpress.router);

app.use(function (req, res, next) {
    res.status(404).send("Sorry can't find that!")
});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});

and file.php is the same as yours

<?php
    $name = $_GET['name'];
    echo $name;
?>

You can see that you don't need to render php file by yourself , because phpExpress.router will take care of all the routes with .php extensions and tries to find these files inside views folder.

Ezzat
  • 931
  • 6
  • 13
  • When I put file.php in the views folder and route it with render, it returns null. Why isn't the file retrieving information from the GET request? And how can you allow the file to retrieve the information? – jeremye May 06 '17 at 22:18
  • I put it in views, and changed the GET request url to just the file name and it worked. So 1) Thank you very much, and 2) why does it not work if the url is `views/file.php`? – jeremye May 06 '17 at 22:43
  • As you can see `app.set('views', path.join(__dirname, '/views'));` we set the template engine views folder here to our `/views` directory , that is why express know the template files paths will be under views directory. What happens when you call GET `views/file.php` is that our express router will see that you have `.php` extension then it will use `phpExpress.router` which will read the url path and tries to find `views/file.php` under `/views` directory. and you don't have `/views/views/file.php` so , it will throw an error. – Ezzat May 06 '17 at 22:59
  • But it doesn't give an error, it finds `views/file.php` but, like before, outputs the raw text contents of the file – jeremye May 06 '17 at 23:16
  • Remove `app.use('/', express.static(__dirname));` and it will throw the error – Ezzat May 06 '17 at 23:47
  • Yeah, I just realized that. Thank you so much for your help – jeremye May 07 '17 at 00:03
0

The res.render() function Renders a view and sends the rendered HTML string to the client. Node is therefore treating the file you are sending as a template file to be rendered to the view. You should try res.sendFile instead.

update: I think you need to expose a route in your index.js that sends the file(that is, makes the file available to an external script). And then you can send a GET request to that url to get the file.

Mekicha
  • 811
  • 9
  • 21
  • I'm sorry if I wasn't clear enough: the rendering of the php file for the homepage works, I do want the HTML there. There is another php file on the server located at path "folder/file.php" it is that get request that isn't working. – jeremye May 06 '17 at 20:05
  • Ah, I probably misunderstood what you meant. I think you need to expose a route in your index.js that sends the file(that is, makes the file available to an external script). And then you can send a GET request to that url to get the file. – Mekicha May 06 '17 at 20:12
  • Oh, gotcha. I will try that right now. Do you mind adding that clarification to your answer? – jeremye May 06 '17 at 20:13
  • It doesn't work, still returns the entire contents. My entire root directory is the public folder, so I don't think creating that route does anything. – jeremye May 06 '17 at 20:17
  • It seems like the issue is PHP just isn't running on the file, it is being treated as a plain text file. – jeremye May 06 '17 at 20:23
  • Ah, maybe you can take a look at the answer to this question:https://stackoverflow.com/questions/16333790/node-js-quick-file-server-static-files-over-http. It might be of help – Mekicha May 06 '17 at 20:26
  • I'm not sure those answers can help me here, because the file is available, just not being processed. I added an example to my question, to show exactly what is happening and what I would like to happen. – jeremye May 06 '17 at 20:48
  • The example makes it clearer what you want. I don't know if that's possible in a nodejs environment since you need the php file running in a server for it to process that request. – Mekicha May 06 '17 at 21:06
  • But do you know what exactly changes just by starting with node.js and an index.js file? Because my javascript and php files remain untouched, but I get two different responses. – jeremye May 06 '17 at 21:08