Strange pjax behavior: GET request initiates after a pjax request - pjax

The problem is, as soon as pjaxed request finishes, pjax also initiates a normal GET request.
My codes are like this:
$(document).on('pjax:end', function(event){
alert("end");
inpjax = false;
});
$(document).on('pjax:timeout', function(event) {
alert("timeout")
event.preventDefault();
});
$(document).on('pjax:error', function() {
alert("error");
});
$(document).on('pjax:success', function() {
alert("success");
});
$(document).ready(function(e) {
inpjax = false;
$('.pj').click( function(e) {
e.preventDefault();
if(!inpjax)
{
inpjax = true;
$.pjax({
timeout: 5000,
url: $(this).attr('href'),
container: '#codeport'
});
}
});
});
As you can see, it should give me an alert on different stiuations, but I only get alert on pjax:end event, and after that alert, pjax initiates normal GET request, timing is like this:
[17:36:02.002] GET http://localhost/abstract?_pjax=%23codeport [HTTP/1.1 200 OK 86 ms]
[17:36:02.170] GET http://localhost/abstract [HTTP/1.1 200 OK 73 ms]
I don't get timeout, error or success alert.
What could be causing this? Please help...
SOLUTION:
The problem turned out to be that my serverside code was responding with a full page, and that was causing a second GET request. So if this problem happens to you too, make sure that your server side code responds correctly to PJAX requests.

example:
<!DOCTYPE html>
<html>
<head>
<!-- styles, scripts, etc -->
</head>
<body>
<h1>My Site</h1>
<div class="container" id="pjax-container">
Download content from the other site ?.
</div>
</body>
</html>
Try to add pjax to an element which you want to get event messages from like $(document).pjax('a', '#pjax-container')

Related

Why does an await within a server endpoint blocks other incoming requests?

I have two different versions of an endpoint for testing.
The first one is this:
app.get('/order', async (req, res) => {
console.log("OK")
getPrintFile()
})
And the second one is this:
app.get('/order', async (req, res) => {
console.log("OK")
await getPrintFile()
})
the getPrintFile is an async function that returns a promise when every operation is done. Withing the function I upload an image to a
server, I download a new image, and re upload that new image to another server.
I noticed that in the first example, without the await, if I send a lot of requests to the "order" endpoint,
I get the "OK" instantly for each request, which is what I want because that "OK" will get replaced by a res.status("200"). I need
to send a status 200 immediatly after getting the endpoint hit for various reasons. Then I don't care how long it takes for the server to do all the processing of the images/uploading, as long as the res.send(200) is executed instantly when there is a new incoming request.
However, when I use the await, even if new requests are coming in, it takes a lot to display the next "OK" if a previous request
is still processing. Usually it displays the OK only when the code within the getPrintFile function is done executing (that is, images are uploaded and everything is done)
It's like the event loop is blocked but I don't understand why.
What is happening here?
Edit:
So it is clearer, I tested it. If I send 5 requests to the "order" endpoint, the "OK" is displayed in the console immediately for all of them, and then the images are processed and uploaded at their own speed for each request. In the second example, if I send 5 requests, the first OK is displayed, and then the remaining 4 are displayed one at a time when the previous request is done executing, or if not exactly in that order, they get logged with tremendous delay, and not consecutively
I'll try to answer based on my understanding of your problem. The first thing missing is the res.sendStatus(200) in your examples to make them actually work. But then, indeed it happens as you describe it: the /order endpoint actually is "blocking" you from making another request as the await is blocking you from reaching the final statement (res.send). Here a full example
const express = require("express");
const app = express();
async function takeTime() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("resolved");
resolve(1);
}, 2000);
});
}
app.get("/order", (req, res) => {
console.log("ok"); // Happens immediately
await takeTime();
return res.sendStatus(200);
});
app.get("/", async (req, res) => {
console.log("ok"); // Happens immediately
takeTime();
return res.sendStatus(200);
});
app.listen(3000, () => {
console.log("server running on port 3000");
});
When testing the API (i.e. from Postman), you won't be able to run immediately another request on the /order endpoint, because you will be locked in waiting for the answer of the request just sent.
In the / endpoint, on the other hand, you will receive immediately the HTTP 200 response (as there is no await) and the code for the takeTime function will keep running asynchronously until it's done.
Here you can find more information, I hope it's useful.
Edit 1
here I add the .html page I'm using to test the await loop requests
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script>
for (let i = 0; i < 10; i++) {
fetch("http://localhost:3000/order");
}
</script>
</html>
The fetch is not working for me in the browser, but having a web page making those request works

Saving FB access token from FB JS SDK to DB

I am implementing 'Login with FB' for my web app using FB JS SDK. I have got the user to return the access token in the response inside the statusChangeCallback function. However, I am not sure about the best method to store this info to a DB for later use (getting data from graph api). How can the access token and other user info be saved into a DB?
In an attempt to post this data on an API, I have tried to serve this html using an express app but the facebook login popup shows blank where it should say "continue as such and such.."
Should there be a separate API that I should post this data to?
Any clue is appreciated!
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login JavaScript Example</title>
<meta charset="UTF-8">
</head>
<body>
<script>
function statusChangeCallback(response) { // Called with the results from FB.getLoginStatus().
console.log('statusChangeCallback');
console.log(response); // The current login status of the person.
if (response.status === 'connected') { // Logged into your webpage and Facebook.
testAPI();
} else { // Not logged into your webpage or we are unable to tell.
document.getElementById('status').innerHTML = 'Please log ' +
'into this webpage.';
}
}
function checkLoginState() { // Called when a person is finished with the Login Button.
FB.getLoginStatus(function(response) { // See the onlogin handler
statusChangeCallback(response);
});
}
window.fbAsyncInit = function() {
FB.init({
appId : '{app-id}',
cookie : true, // Enable cookies to allow the server to access the session.
xfbml : true, // Parse social plugins on this webpage.
version : '{api-version}' // Use this Graph API version for this call.
});
FB.getLoginStatus(function(response) { // Called after the JS SDK has been initialized.
statusChangeCallback(response); // Returns the login status.
});
};
function testAPI() { // Testing Graph API after login. See statusChangeCallback() for when this call is made.
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
});
}
</script>
<!-- The JS SDK Login Button -->
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>
<div id="status">
</div>
<!-- Load the JS SDK asynchronously -->
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js"></script>
</body>
</html>
This code is taken from facebook docs: https://developers.facebook.com/docs/facebook-login/web#example

amazon pay error client_Id undefined

I am integrating the amazon pay API in my asp.net code. I have write the following code
<!-- language: lang-js -->
<script type='text/javascript'>
window.onAmazonLoginReady = function () {
amazon.Login.setClientId('<%=ConfigurationManager.AppSettings["lwa_client_id"]%>');
amazon.Login.setUseCookie(true);
};
</script>
<script async type='text/javascript' src='https://static-na.payments-amazon.com/OffAmazonPayments/us/sandbox/js/Widgets.js'></script>
<script type='text/javascript'>
OffAmazonPayments.Button("AmazonPayButton", '<%=ConfigurationManager.AppSettings["merchant_id"]%>', {
type: "PwA",
authorization: function () {
debugger;
loginOptions = { scope: "profile postal_code payments:widget payments:shipping_address", popup: true };
amazon.Login.authorize(loginOptions, "/AmazonProcessing");
},
onError: function (error) {
// something bad happened
}
});
</script>
It render the Amazon Pay button. But when I click on it, It will show the popup with error of 404.
It was working before. I do not change any setting on the Amazon. I have checked the JavaScript Cross origin. I have added the localhost with port.
How to resolve this issue?
The value for client ID is probably not populated correctly from your application settings (error "Unknown client_id" and in the error summary "client_id=undefined").
You should be able to set a breakpoint in the JavaScript on the line with "setClientId" to verify whether the client ID has a value or not.

PubNub keeps receiving one message over and over

Just started with PubNub, and seems that I fail to understand even the simplest possible scenario. I created the following test page:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.15.1.js"></script>
<script>
const pubnub = new PubNub({
publishKey : '<guid>',
subscribeKey : '<one more guid>'
});
pubnub.subscribe({channels: ['3']});
pubnub.addListener({
message: v => {
console.log("on message", v);
},
});
function onClick() {
pubnub.publish({channel: '3', message: 'foo'});
}
</script>
</head>
<body>
<button onclick="onClick()">start</button>
</body>
</html>
Opening it with latest Chrome and clicking "start" button will result in test message being received endlessly over and over. I was under impression that after single client receives a message from a bus, this client will not receive it again. why such behaviour? I understand that I can read all the docs and most probably answer is somewhere deep inside, but tutorial + quickstart gives no clues, and rest of docs are quite huge.
Your example code works perfectly for me. The message published is received one time on the channel "3". One way to validate this is to simultaneously have the PubNub Console open (https://www.pubnub.com/docs/console). Make sure you enter your Publish and Subscribe keys into the console, along with the channel "3". After clicking the "Subscribe" button in the PubNub Console, you should see your test message "foo" appearing once in the "messages" section at the bottom each time you click the "start" button on your test page.
I can see that you're using the latest SDK-JS V4 (perfect starting point)
Your code works!
I would like to point you to a bit of a diff way to init PubNub and few functionalities.
(which are available in their docs)
Please look at the attached link to view my PubNub demo
<script type="text/javascript">
console.log('init PubNub.');
pubnub = new PubNub({
publishKey: 'demo',
subscribeKey: 'demo',
uuid: 'myDemo'
})
console.log("addListener..");
pubnub.addListener({
status: function(statusEvent) {
if (statusEvent.category === "PNConnectedCategory") {
console.log("PNConnectedCategory..");
publishSampleMessage();
}
},
message: function(message) {
console.log("New Message!!", message.message);
},
presence: function(presenceEvent) {
//handle presence
}
})
console.log("Subscribing..");
pubnub.subscribe({
channels: ['myDemo']
});
function publishSampleMessage() {
console.log("Since we're publishing on subscribe connectEvent, we're sure we'll receive the following publish.");
var publishConfig = {
channel: "myDemo",
message: "I'm here, I'm alive!!"
}
pubnub.publish(publishConfig, function(status, response) {
console.log(status, response);
})
}
function onClick() {
publishSampleMessage();
}
</script>

Access another pages inside extension from content script or background page

everyone.
Can anybody tell me how I can access DOM of another pages in my extension from content script or background page? I tried to make a connection from content script to popup.html. But it doesn't work. But the same code works with background.html...
Here's the code I place in myscript.js:
function sendLast(){
var result = document.getElementById('last_3212164'); //document.evaluate("//*[#id='last_3212164']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
alert(result.textContent);
chrome.extension.sendRequest({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
}
var t=setTimeout("sendLast()", 3000);
Here is code from popup.html:
<html>
<head>
<script>
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
alert("Got it!");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
else
sendResponse({}); // snub them.
}
);
</script>
</head>
<body>
Here will be the values
</body>
</html>
This code is supposed to give alert "Got it" every 3 second. But It doesn't do anything, silence... I open Popup.html 1 sec after loading the main page.
If popup is currently opened then you can access its DOM from a background page. If you need it in a content script then you would need to send a request to a background page first.
Lets say you want to read a value of test input field from a popup inside a content script:
content_script.js:
chrome.extension.sendRequest({cmd: "findElementInPopup"}, function(response){
console.log("value:", response);
});
background.html:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if(request.cmd == "findElementInPopup") {
var winArray = chrome.extension.getViews({type:"popup"});
//if popup is opened
if(winArray.length > 0) {
sendResponse(winArray[0].document.getElementById("test").value);
}
}
});
You would need to do all the DOM manipulations in a background page as trying sending whole window through a response back to a content script would result in an error (object structure is too complex for json serialization).

Resources