I'm trying to send a post request to a Drupal .module file from node.js. My problem is that the module file is never executed as php by Apache when the request is made, so instead of getting a response from php, I get the literal code (inside the .module file) as a text string.
I tried enabling .module to execute as php (not sure the security implications) by putting the following in .htaccess:
Addhandler application/x-httpd-php .module
(and virtually every other combination of that command I could find)
But no luck.
I know the post request sent by node.js is perfectly fine because it works when sent to .php files on the same server. I just can't get it to work within a Drupal module. I want it to be sent to a Drupal module because I want to take advantage of Drupal's API (going to be doing a lot of modifications to drupal user tables).
How do I send a post request to a drupal module, programmatically, from node and read its response? I know how to send it to a simple .php file, but not to a drupal module.
You create a menu in module file.
function mymodule_menu() {
$items['post-link'] = array(
'page callback' => 'mymodule_abc_view',
);
return $items;
}
and then send the post request on that menu link through Node.js.
YOURSITENAME/post-link?data1=abc&data2=def
And then fetch the post data on those menu call back function to use drupal_get_query_parameters() function.
function mymodule_abc_view() {
// ...
$parameters = drupal_get_query_parameters();
print "<pre>";
print_r($parameters);
print "</pre>";
}
it may be help for you.
Thanks,
Related
I need to use the res.redirect() to redirect to a data URL using express.
This is my code...
app.get("/",(req,res)=>{
res.redirect("data:text/plain;base64,hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
})
When I use another URL eg: https://www.google.com It works fine.
But when I use a data URL it is not working..
How should I fix it?
I am new to programming and StackOverflow. So, please be kind to me
You could redirect the user to a blob of the dataurl location.
For that just search google for dataurl to blob in js etc.
And also as you are using nodejs you could use the http.request and pipe the response to client just like proxying.
or you could fetch that file with "http.request" and save it in your server and give it when the client needs it
This is likely Chrome issue rather than NodeJS:
https://groups.google.com/a/chromium.org/g/blink-dev/c/GbVcuwg_QjM/m/GsIAQlemBQAJ
In practice, these will be blocked:
Navigations when the user clicks on links in the form of
window.open(“data:…”)
window.location = “data:…”
Meta redirects
I'm trying to run this code
module.exports = async (req, res, next) => {
res.set('Content-Type', 'text/javascript');
const response = {};
res.status(200).render('/default.js', { response });
await fn(response);
};
fn is a function that calls an api to a service that will output to the client something. but its dependent on the default.js file to be loaded first. How can do something like
res.render('/default.js', { response }).then(async() => {
await fn(response);
};
tried it, but doesn't seem to like the then()
also, fn doesn't return data to the client, it calls an api service that is connected with the web sockets opened by the code from default.js that is rendered.
do i have to make an ajax request for the fn call and not call it internally?
any ideas?
Once you call res.render(), you can send no more data to the client, the http response has been sent and the http connection is done - you can't send any more to it. So, it does you no good to try to add something more to the response after you call res.render().
It sounds like you're trying to put some data INTO the script that you send to the browser. Your choices for that are to either:
Get the data you need to with let data = await fn() before you call res.render() and then pass that to res.render() so your template engine can put that data into the script file that you send the server (before you send it).
You will need to change the script file template to be able to do this so it has appropriate directives to insert data into the script file and you will have to be very careful to format the data as Javascript data structures.
Have a script in the page make an ajax call to get the desired data and then do your task in client-side Javascript after the page is already up and running.
It looks like it might be helpful for you to understand the exact sequence of things between browser and server.
Browser is displaying some web page.
User clicks on a link to a new web page.
Browser requests new web page from the server for a particular URL.
Server delivers HTML page for that URL.
Browser parses that HTML page and discovers some other resources required to render the page (script files, CSS files, images, fonts, etc...)
Browser requests each of those other resources from the server
Server gets a request for each separate resource and returns each one of them to the browser.
Browser incorporates those resources into the HTML page it previously downloaded and parsed.
Any client side scripts it retrieved for that page are then run.
So, the code you show appears to be a route for one of script files (in step 5 above). This is where it fits into the overall scheme of loading a page. Once you've returned the script file to the client with res.render(), it has been sent and that request is done. The browser isn't connected to your server anymore for that resource so you can't send anything else on that same request.
i have a file on my "website/folder/file" which i would like to redirect to prevent user to access that file, without using htaccess.
My file is a huge DB containing url's, i don't want the users access to that file by typing the direct URL to the file.
That file is called & used by my chrome extension, who block access to the user if he tries to reach one of the url's in that DB.
Problem is by typing the direct url to that file we have access...
i tried everything with the .htaccess file, i know we can block, redirect, etc with the .htaccess file but if i redirect or block the url of the DB with the htaccess, my extension doesn't work anymore because the DB is blocked by the htaccess file.
so i'm trying to find a solution, maybe is an !
my background.js
'use strict';
let db = []; // session Global
// ----- parse & cache the database data
fetch('http://thmywebsite.com/folder/db.dat')
.then(response => response.text())
.then(text => { db = text.trim().split(/[\r\n]+/); })
.catch(error => console.log(error));
chrome.webRequest.onBeforeRequest.addListener(details => {
let url = new URL(details.url);
return { cancel: url && url.hostname && db.includes(url.hostname) };
},
{ urls: ["http://*/*", "https://*/*"] },
["blocking"]
);
chrome.extension.isAllowedIncognitoAccess(function (isAllowedAccess) {
if (isAllowedAccess) return; // Great, we've got access
})
You can't realistically do this. You can't block a resource that needs to be available publicly (by your client-side script).
You can potentially make this a little harder for someone wanting your DB, by perhaps sending a unique HTTP request header as part of your fetch(). You can then check for the presence of this header server-side (in .htaccess) and block the request otherwise. This prevents a user from casually requesting this file directly in their browser. However, this is trivial to bypass for anyone who looks at your script (or monitors the network traffic) as they can construct the request to mimic your script. But let's not forget, your script downloads the file to the browser anyway - so it's already there for anyone to save.
You need to rethink your data model. If you don't want the DB to be publicly accessible then it simply can't be publicly accessible. Instead of your script downloading the DB to the client and processing the request locally, you could send the request to your server. Your server then performs the necessary lookup (on the "hidden" database) and sends back a response. Your script then acts on this response.
my .htaccess works fine when I type manually a wrong url it redirects to my custom 404 page. Here is my .htaccess (this the hole content (no other redirects)):
RewriteEngine on
ErrorDocument 404 http://codeexample.local/404.shtml
Now in my Silex based application I return a 404 status code if the client tries to edit a non existent client. Even though the status code is indeed 404 as i can see with curl -v. But for some reason it is not redirected to 404 error page.
Here is how I access the url:
http://codeexample.local/index.php/2/edit
Here is my index.php edit route section:
$app->match('/{id}/edit', function (Request $request, $id) use ($app) {
try {
$clientController = new ClientController($request, $id);
return $clientController->editAction($app);
}
catch(\Exception $e){
return $e->getMessage();
}
})
->assert('id', '\d+')
->method('GET|POST');
in my editAction method I am checking if the client exists in the database otherwhise I am returning a response like this:
$response = new Response(
'',
Response::HTTP_NOT_FOUND,
array('content-type' => 'text/html')
);
$response->prepare($request);
$response->send();
return $response;
Thanks
you should redirect to the error page.
$app->redirect( '/404.shtml' );
In your code you are creating a new Response with a statuscode. This is too late for the apacheserver to react.
And other idea is to call the function which creates the errorpage, but i would say don't do that to keep the code clean.
Your expectations are a bit off here, possibly. The web server will handle requests for addresses it has no knowledge of with a 404 response, and you can also provide it with some HTML to send along with the 404 response. But it's the 404 response that is really the important bit.
Telling the web server that 404.shtml is the mark-up to send back to the browser is not like a redirect to that page, it simply uses the contents of that file for the HTML to send back with the 404 response.
Silex knows nothing about that, as the web server's 404-handling is long since fallen out of the picture by the time Silex gets anywhere near the request. When there's a 404 condition at the Silex end of things you need to do two things: return a 404 code in the response (you're doing that now), and you can optionally send some content back too (like the markup in that 404.shtml file). If you want to have the same 404 mark-up as the 404.shtml that the web server uses... read that file and return it as the content with your 404 response.
You could try to go a different route and rejig your web server 404 to return the result of a Silex-routed URL, and then use that same route internally for the content of 404s from Silex too, but I think it's the wrong approach for the web server to be bugging PHP/Silex for a response to a request which has already been identified as invalid.
What you really really do not want to do is redirect from Silex to a doc containing mark-up for a 404. What that will do is tell the user agent that the URL it tried was incorrect, and it should try another one (as provided by the redirect header), which will then return a 404 message to the human in the mark-up, but will be returning 200-OK to the user agent. So in effect when a user agent browses to /someBadPage.html you'd be telling them the correct document for that URL is /404.html. Not that /someBadPage.html does not exist.
I am coming from PHP where an AJAX call from jQuery is done like this.
html:
$('a').click(function(){
var mydata = 'abc123';
$.post( 'process.php', { mydata:mydata}, function(data){
$('body').append('<h1>'+data+'</h1>');
});
return false;
});
php:
$post = $_POST['mydata'];
echo $post;
Question: how can i replace the PHP part with node.js to do the same thing?
also i would need to change this part of jQuery $.post( 'process.php', ...
would that look like this? $.post( 'process.js', ...?
I saw this post but i couldnt translate it from php to node
This helped out, from "Node.js for PHP developers"
In PHP, a PHP file represents an HTML page. A web server, such as Apache, accepts
requests and if a PHP page is requested, the web server runs the PHP. But in Node.js,
the main Node.js file represents the entire web server. It does not run inside a web server
like Apache; it replaces Apache.