I'm trying to using server-side render for my React web application (redux + react-router).
Server returned rendered HTML properly with API call on the server side.
But when browser receives the HTML document, it recalls API second time.
So it makes API call twice: 1 on server and 1 on the client with same result data.
Why client recall the API and How to avoid that duplicate call?
Check if the html returned contains script which calls the server. If that's the case, you have to either:
Modify this call to receive this piece of data in an asynchronous way, so the page doesn't get reloaded
Modify the returned HTML page, so it doesn't execute any further calls
It's a bit hard to speculate without an example
Related
I made a nodejs application that starts from index.js.
Then, index.js launches puppeteer and injects bot.js on a headless-api page by addscripttag function.
I made index.js sets a cookie for conveying initial values before injecting javascript, but I need more common way to exchange data.
I thought two ways; the first is using cookie, and the second is networking via socket connection.
Is there other way for send and receive data between index.js(node) and puppeteer(headless chrome)?
First, puppeteer IS nodejs side application, so they have a single environment and you don't need to "send" anything. Just pass data around as you'd do in any other JS code. I assume you want to transfer data between page and nodejs then.
To pass data from nodejs to page use page.evaluate. You can call any code in page context, ranging from simply setting some variables to directly calling whatever functions with necessary arguments.
To initiate transfer from page side to nodejs, first register a nodejs-side callback function with page.exposeFunction and then call it from page code and it will be executed in nodejs context. Just like in previous case, everything else depends on code of that function. It can be as simple as storing whatever argument you pass to it in some variable or directly perform with data pretty much whatever you want.
So far when creating AJAX requests I have been posting to a separate PHP file. Is it possible to create a jQuery AJAX request that calls a PHP function rather than posts to a separate page?
If you could send me any examples or documentation would be great.
I believe there's a fundamental misunderstanding of how the technology works here.
AJAX (Javascript), Flash, or any client-sided technology cannot directly call PHP functions (or other languages running on the server).
This is true for going the other way around as well (eg: PHP can't call JS functions).
Client and server codes reside on different machines, and they communicate through the HTTP protocol (or what have you). HTTP works roughly like this:
Client (eg: browser) sends a REQUEST -> Server processes request and sends a RESPONSE -> Client gets and displays and/or processes the response
You have to see these requests and responses as messages. Messages cannot call functions on a server-side language directly 1, but can furnish enough information for them to do so and get a meaningful message back from the server.
So you could have a handler that processes and dispatches these requests, like so:
// ajax_handler.php
switch ($_POST['action']) {
case 'post_comment':
post_comment($_POST['content']);
break;
case '....':
some_function();
break;
default:
output_error('invalid request');
break;
}
Then just have your client post requests to this centralized handler with the correct parameters. Then the handler decides what functions to call on the server side, and finally it sends a response back to the client.
1 Technically there are remote procedure calls (RPCs), but these can get messy.
AJAX requests call a URL (make a HTTP request), not a file, in most cases the URL is translated by the server to point at a file (or a php script in your case), but everything that happens from the HTTP request to the response that is received is up to you (on your server).
There are many PHP frameworks that map URL's to specific php functions, AJAX is just an asynchronous way to access a URL and receive a response.
Said URL CAN trigger the server to call a specific function and send back a response. But it is up to you to structure your URL's and server side code as such.
If you're asking whether you can call any arbitrary PHP function with AJAX the answer is no*, for obvious security reasons (in addition to the technical reasons). You could make a PHP script that does different things depending on what parameter it's given (for example, execute a single function) if you don't want to create multiple separate files.
*Although you could make a script that would execute any arbitrary PHP command coming from the client, but that would be very, very, very unwise.
Short answer is "no" but the real answer is that you can fake it. NullUserException's answer is good. You create a server that will take the function name and its parameters. Then the server executes the function, and returns the value.
This was done a while back via a protocol called XML-RPC. There was also an effort called JSON-RPC that used some JS techniques.
One things that's cool about JS is that you can do things like this:
var base64_decode = create_remote_call('base64_decode');
function create_remote_call(name) {
return function(x) {
jQuery.getJSON('url/server.php',
{func:name,arg:x},
function(d){return d;});
}
}
A call to base64_decode('sarefdsfsaes') will make a ajax request and return the value.
That code probably won't work because it hasn't been tested, but it's a function that produces a function that will call the server, and then return the value. Handling more than one argument requires more work.
All that said... in my experience, it's usually good to make all network communications explicit instead of disguising it as a regular function.
you may achieve the same result using a bridge, like my phery library http://phery-php-ajax.net you can call PHP functions directly from Javascript and deal with the value. The AJAX is bound to DOM elements, so you can manipulate the calling DOM or just use jQuery from the PHP side. An example would be:
Phery::instance()->set(array(
'phpfunction' => function(){
return PheryResponse::factory()->jquery('body')->addClass('whoops');
}
))->process();
and in the javascript side (or HTML)
phery.remote('phpfunction');
the equivalent to the https://stackoverflow.com/a/7016986/647380 from John Kawakami answer, using phery is:
function base64($data){
return !empty($data['encode']) ? base64_encode($data['content']) : base64_decode($data['content']);
}
Phery::instance()->set(array(
'base64' => 'base64'
))->process();
function base64(content, decode, output){
phery.remote('base64', {'content': content, 'encode': decode ? 1 : 0}, {'type':'text'}).done(output);
}
base64('asdf', false, function(data){
console.log(data); // or assign to some variable
});
since AJAX is asynchronous and you can't just return a value from the AJAX call, you need a callback, but this would suffice.
I have a main view function for my application. After logging in successfully this main view method is called and is expected to render the template.
But I have to perform some calculations in this view method [I am checking certain conditions about the user by making facebook graph api request.]
Thus it takes 2~4 seconds to load.
How do I show this loading scene since the template is rendered by return statement and thus is executed only when the process is complete.
Should I make 2 views , one for showing loading and the other one for calculating and keep making AJAX request to other view method to check if the process is complete or not ?
You should indeed make two views, one to only return the page showing the loading UI and one to perform the long task.
The second view will be called using an AJAX request made from the "loading" page. The response from the AJAX request will notify your "loading" page that it is time to move on.
You need to make sure the AJAX request's duration won't exceed the timeout of your server (with ~10 seconds, you should be fine).
You need to run your Graph API requests in a task executed asynchronously, allowing you to return a HttpResponse without waiting for the task to finish.
Celery will allow you to do just that.
You then need a way to notify your client that the asynchronous task has finished.
I see two ways to do that:
Making AJAX requests at regular intervals to a view that will check if the task is finished.
Using WebSockets.
The first approach is the simplest but has the drawback of making a lot of useless requests and of being less reactive.
Using WebSockets on the other side will require more configuration as an external app is required (ex: django-socketio or swampdragon).
If it is the only place where you need notifications from server to client, using WebSockets seems to be overkill.
Background:
I am using node.js and a module called scrap (with jQuery) to screen scrape a website and display some of its information on my own website
To do this, I am making a JSON of data available at a certain path in my website so that the client can retrieve the information when they load the client-side javascript
I am exporting a variable in the JSON called isLoaded that will be true if the server has finished loading all of the data for the json
Problem:
Since scrap and jquery make asynchronous calls and load them into the data variable that is sent with the JSON, all of the information might not be included in the JSON just yet
This is fine most of the time, but take for instance the example when I access the page that loads that data and the server is still populating the data that is exported with the JSON object
This essentially requires the client to refresh the page until all of the data is loaded.
Question:
Is there a way to continuously call $http.get(...path...) inside the client-side javascript until the variable 'isLoaded' returns true?
Note:
I have already tried a loop but for some reason the loop can't get new data once it's running. Also, I have tried to the best of my ability to find an answer on Google with no luck. If anyone could point me in the right direction, I would appreciate it.
I am trying to make an html app for local use, consisting of an HTML page using Google Maps API V3, a SQLite database, and a SimpleHTTPServer script.
The workflow is the following:
User starts the server and opens the page, which contains a map with a set of markers, and a form with filters similar to those of Google Fusion Tables;
User interacts with form, which sets some parameters for a query;
When the user clicks "Submit", page sends a request to HTTPServer, whose request handler queries the SQLite database and returns the result as JSON/JSONP/something-else;
Some function takes back the data and map is updated;
My doubts are more conceptual than anything else, and specifically I would like to know (how/where to look for):
How should I send a request for the server in javascript, and how to listen back to it?
How should the server send data to the request, in order to update its value instead of refreshing the page?
Sorry if my questions seem obvious, but HTTP is something very new to me, and so is client-server communication.
Thanks for reading!
I think you can use CGIHTTPServer.
ref:
http://pydoc.org/2.5.1/CGIHTTPServer.html
Q:How should I send a request for the server in javascript, and how to listen back to it
A:Please google "ajax". "jquery" is one of the most convenient javascript library for ajax.
Q:How should the server send data to the request
A:just use "print" in python script which is called by CGIHTTPServer.
In this case, the output of "print" will be the response to http client(web browser).
In the script mentioned above, you should extract request parameter sent by http client,
with "do_Get()" or do_Post() function.