I have a URL to the latest Webcam shot http://cam.hackerspace.sg/last.jpg and it redirects to its source filename for example. 1364124301.jpg
I want to read the Epoch '1364124301' in Javascript so I can convert it to a timestamp. Though logging the img.src shows the old original URL. So how do I get '1364124301' without using Jquery?
Thanks!
Using JavaScript alone it seems impossible to get the redirect location: A XMLHTTPRequest hides the redirect transparently and an iframe does not allow to access it's URL if it's from another domain.
If you have a PHP enabled website the following will allow to get the redirect. (All code is without any capture of error conditions for simplicity, one will need to add error handling before using it).
First, to get the redirect location, some PHP, the file is called getRedirect.php:
<?php
$redirect = '';
$urlToQuery = $_GET['url'];
$urlParts = parse_url($urlToQuery);
$host = $urlParts['host'];
$path = $urlParts['path'];
$address = gethostbyname ($host);
$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect ($socket, $address, 80);
$request = 'GET '.$path.' HTTP/1.1'."\r\n";
$request .= 'Host: '.$host."\r\n";
$request .= 'Connection: Close'."\r\n\r\n";
socket_write($socket, $request);
$answer = socket_read($socket, 8192);
socket_close($socket);
$answerLines = explode("\r\n", $answer);
foreach ($answerLines as $line) {
$lineParts = explode(':', $line, 2);
if($lineParts[0] == 'Location') {
$redirect=trim($lineParts[1]);
break;
}
}
header('Content-Type: text/plain; charset=us-ascii');
header('Content-Length: '.strlen($redirect));
echo $redirect;
?>
Second, the image display page which uses JavaScript to set up the image and to query the redirect location (via XMLHTTPRequest to getRedirect.php):
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function updateImage() {
var imgParent = document.getElementById("imgContainer");
// delete existing image if exists
var imgChild = imgParent.firstChild;
if(imgChild!=null) imgParent.removeChild(imgChild);
// insert new image with actual redirect
var newImg = document.createElement("img");
newImg.src = "http://cam.hackerspace.sg/last.jpg";
imgParent.appendChild(newImg);
var redirect = getRedirect("http://cam.hackerspace.sg/last.jpg");
var timestamp = redirect.substring(redirect.lastIndexOf("/") + 1, redirect.lastIndexOf("."));
document.getElementById("imageDate").innerHTML="Timestamp="+timestamp;
}
function getRedirect(url) {
var redirect = "";
var req = new XMLHttpRequest();
req.open('GET', 'getRedirect.php?url='+url, false);
req.onreadystatechange = function () {
if (req.readyState == 4) {
redirect = req.responseText;
}
};
req.send(null);
return redirect;
}
</script>
</head>
<body>
<button onclick="updateImage();">update image</button>
<div id="imgContainer"></div>
<p id="imageDate"></p>
</body>
</html>
Using XMLHTTPRequest, you can read the newUrl after being redirected in XMLHTTPRequest.responseURL property. By comparing the newUrl with the originUrl, you can find out if it's a redirect.
Related
Current setting:
In the same PHP document I have a PHP randomizer function and the HTML that calls that function -- a separate txt document with strings that are called by the php function:
Function
<?php
function rand_line($fileName, $maxLineLength = 4096) {
$handle = #fopen($fileName, "strings.txt");
if ($handle) {
$random_line = null;
$line = null;
$count = 0;
while (($line = fgets($handle, $maxLineLength)) !== false) {
$count++;
if(rand() % $count == 0) {
$random_line = $line;
}
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
fclose($handle);
return null;
} else {
fclose($handle);
}
return $random_line;
}
}
?>
I call the function in the HTML using:
<?php echo rand_line("strings.txt");?>
<input type="button" value="Another String" onClick="window.location.reload()">
This tends to be slow when multiple users access the page and press the button to obtain a new status.
What I would like to achieve:
Improve the performance and make the whole thing not so heavy: maybe the randomizer is unnecessarily complicated and I could work with AJAX calls for example, but if possible keeping the string list inside the strings.txt file and separated from the PHP script and HTML.
Sorry if I don't know what I'm talking about... I'm not a proficient programmer. Just a guy that hacks stuff together once in a while :)
You really don't want to use window.location.reload();
That is terrible... You do not want to refresh a page...
location.reload() sends http request for a whole new page (whole HTML), and then not only that your browser needs to render whole HTML again, you have to transfer more duplicated data through a network, from point A to point B.
You should send HTTP request only for a data that you need (you don't need whole HTML again, you loaded it the 1st time you visited page).
Instead, use XMLHttpRequest javascript library (AJAX) to request only for a portion of data (in your case => random line string)
HTML:
<!DOCTYPE html>
<html>
<head lang="en">
<script type="text/javascript">
function loadDoc(url, cfunc) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
cfunc(xhttp);
}
};
xhttp.open("GET", url, true)
xhttp.send();
}
function randomLine(xhttp) {
alert(xhttp.responseText);
}
</script>
</head>
<body>
<input type="button" value="Get random line" onClick="loadDoc('http://localhost:8080/myScript.php', randomLine)">
</body>
</html>
PHP:
myScript.php
<?php
function rand_line($fileName, $maxLineLength = 4096)
{
...
}
echo rand_line("strings.txt");
?>
*EDIT #2*
Fully-functioning script. Grabs initial strings via PHP, and stores in array for later JavaScript usage. Minimizes # of calls.
PHP to grab strings from file; generates a default (random) string, as well as an array of strings for later use with button.
/**
* #input array $file
* #return array (mixed) [0] => string, [1] => array
*/
$randomStringFromFile = function($file) {
if (!$file) return false;
/**
* #return Removes carriage returns from the file
* and wraps $val with single-quotes so as
* to not break JavaScript
*/
$add_quotes = function(&$val) {
return str_replace("\n", "", "'$val'");
};
return [$file[rand(0, count($file)-1)], array_map($add_quotes, $file)];
};
$randomString = $randomStringFromFile( #file('strings.txt') ) ?: false;
JavaScript
<div id="string_container"><?php echo $randomString[0]; // defaults random string to page ?></div><br>
<button onclick="getString();">Another String</button>
<script>
var getString = function() {
var arr = [<?php echo implode(',', $randomString[1]); ?>],
setString = document.getElementById('string_container').innerHTML = arr[Math.floor(Math.random() * arr.length)];
};
</script>
Place the above in your page and you should be good to go.
EDIT (ORIGINAL)
We can remove PHP from the equation entirely using the following (fastest method):
<div id="string_container"></div><br>
<button onclick="getString();">Another String</button>
<script>
var getString = function() {
var request = new XMLHttpRequest(),
file = 'strings.txt';
request.open('GET', file);
request.onload = function() {
if (request.status === 200) {
var arr = request.responseText.split("\n"), /** assuming line breaks in file are standard carriage returns (Unix); "\r" if Windows */
setString = document.getElementById('string_container').innerHTML = arr[Math.floor(Math.random() * arr.length-1)];
}
};
request.send();
};
</script>
ORIGINAL w/PHP
We can simplify the PHP even further, removing loops from the equation altogether.
$randomStringFromFile = function($file) {
if (!$file) return false;
return $file[rand(0, count($file)-1)];
};
echo $randomStringFromFile( #file('strings.txt') ) ?: 'No worky!';
Using file() will return the contents in an array, thus allowing you to simply select a key at random and return the value.
NOTE On average, $file[rand(0, count($file)-1)] outperformed array_rand() (E.g. $file[array_rand($file)];) when selecting a key at random. By negligible amounts, have you.. ~0.0002s vs ~0.0005s, respectively.
You can simplify your code
function rand_line($fileName, $maxLineLength = 4096) {
$f = file($fileName);
$length = $maxLineLength + 1;
do {
$line = $f[array_rand($f)];
$length = strlen($line);
} while ($length > $maxLineLength);
return $line;
}
Creating a CMS and I want to create buttons for user to style the page.
//customize.php
<body class = "body">
<input type = "color" name = "bgColor" id = "bgColor">
<button onclick = "changeColor()">Change Color</button>
</body>
I'm parsing my css in php so I can update the css through ajax.
//style.js
function changeColor(){
var request = new XMLHttpRequest();
var getbgColor = document.getElementById("bgColor").value;
request.onreadystatechange = function(){
if(request.status == 200 && request.readyState == 4){
//I want to send $mycolor back to the client side so user can see
//how their page would look like
var asx = request.responseText;
document.body.style.backgroundColor = asx;
}
};
request.open("GET","mode.php?theColor=" + getbgColor,true);
request.send();
Parsing css in php
//mode.php
<?php
header("Content-type: text/css; charset: UTF-8;");
$mycolor = (isset($_GET['theColor'])) ? $_GET['theColor']: false;
?>
.body{
background-color: <?php echo $mycolor; ?>;
}
I have another file call showPage.php that will have the style manufactured from the customize.php file, but I can't get it to work. What I keep getting is false from $mycolor. Can't seem to figure out what I'm doing wrong. I haven't taught myself jQuery yet, so if you assist, please no jQuery. (thanks for the assistance)
I am trying to make an interactive map that multiple users will be able to draw on and see each others edits live. My attempts so far have not really worked so far. Essentially, in the end, I'd like to have "rooms" that multiple users can join and then write on their own maps but for now I'd like to get it just working in general.
My thought process was this: get a script that auto refreshes an image on a webpage without refresh, make the canvas have a static background of the map I want people to write on, take what they've drawn and save it to a file every x milliseconds, combine the image that is constantly being updated with one that has all other edits, make that final image a second background image of the canvas that auto refreshes.
Now, this is probably horrifically wrong. Here is the code I have so far:
HTML/JS:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="sketch.js"></script>
<title>title</title>
<style>
body{text-align:center;}
div{padding:10px;}
img{border:2px solid #fff;border-radius:7px;}
</style>
</head>
<body onload="toImage(); saveImage(); combineImages();">
</div>
<div class="tools">
Download
</div>
<canvas id="colors_sketch" width="700" height="700"></canvas>
<img id="canvasImg" src="">
<script type="text/javascript">
$(function() {
$('#colors_sketch').sketch({defaultColor: "#ff0"});
});
function toImage() {
setInterval(function() {
var canvas = document.getElementById('colors_sketch');
var context = canvas.getContext('2d');
// save canvas image as data url (png format by default)
var dataURL = canvas.toDataURL();
// set canvasImg image src to dataURL
// so it can be saved as an image
document.getElementById('canvasImg').src = dataURL;
document.getElementById('colors_sketch').style.background = 'url(images/final_img.png), url(img/p1.jpg)';
}, 100);
}
function saveImage() {
setInterval(function() {
var canvas = document.getElementById('colors_sketch');
var context = canvas.getContext('2d');
// save canvas image as data url (png format by default)
var dataURL = canvas.toDataURL();
var onmg = encodeURIComponent(dataURL);
var xhr = new XMLHttpRequest();
var body = "img=" + onmg;
xhr.open('POST', "script.php",true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Content-Length", body.length);
xhr.setRequestHeader("Connection", "close");
xhr.send(body);
xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {
document.getElementById("div").innerHTML = xhr.responseText;
} else {
document.getElementById("div").innerHTML = 'loading';
}
}
}, 1000);
}
function combineImages() {
setInterval(function() {
$.ajax({
url: 'combine.php',
success:function(response){
alert(response);
}
});
}, 2000);
}
</script>
</body>
</html>
script.php:
<?php
// requires php5
define('UPLOAD_DIR', 'images/');
$img = $_POST['img'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . 'one.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
combine.php:
<?php
$image_1 = imagecreatefrompng('images/one.png');
$image_2 = imagecreatefrompng('images/final_img.png');
imagealphablending($image_1, true);
imagesavealpha($image_1, true);
imagecopy($image_1, $image_2, 0, 0, 0, 0, 100, 100);
imagepng($image_1, 'images/final_img.png');
?>
now I'm about to scrap this whole idea just because it's not doing anything that I want it to do and it just seems to be a huge mess. Is there a completely different way of going about what I'm trying to accomplish or is there a way to actually make this work?
There are many ways to build live web applications, but the best and most modern way is to use WebSocket. You can still use older methods such as long pooling and methods that rely on timeouts.
On the client you will need a minimum of four major parts.
Websocket connector (vanilla or a library like socket.io)
Up syncing (Binding to events and notifying the connector)
Down syncing (Replicating events sent by other clients from the connector)
The canvas or WebGL related logic (input/output, drawings, shapes, etc)
On the server you will need messaging system that will relay events from a client to all other subscribed clients.
This is really easy with node.js and socket.io or ratchet for PHP.
Here is a tutorial for Node.js (Node + Express + Socket.io)
Here is an example of a socket.io client written in PHP
trying to change a php variable via js and echo back but its not working, been on it for days!!
I have a function handleServerResponse() called below, that alerts connection status, and getting the ok at status 200 so cant understand why my php variabe is not changing! driving me insane!
function process() // send the info to the server
{
if(xmlHttp)
{
try
{
xmlHttp.open("GET","myFile.php?phpvar="+jsvar,true);
xmlHttp.onreadystatechange = handleServerResponse; //alerts connection status = all ok
xmlHttp.send(null);
}
catch(e)
{
alert(e.toString());
}
}
}
// server side script
<?php
echo '<?xml version="1.0" encoding = "UTF-8" standalone = "yes" ?>';
$phpvar;
$phpvar = $_GET['phpvar'];
echo "new phpvar value = ".$phpvar;
?>
Any help at all would be greatly appreciated.
Cheers
The following code achieves the aim you've stated. Not sure what your problem is, since you've neglected to post a complete example.
phpVarTest.html
<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
function byId(e){return document.getElementById(e);}
window.addEventListener('load', onDocLoaded, false);
function myAjaxGet(url, callback)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function()
{
if (this.readyState==4 && this.status==200)
callback(this);
}
ajax.onerror = function()
{
console.log("AJAX request failed to: " + url);
}
ajax.open("GET", url, true);
ajax.send();
}
function onDocLoaded()
{
byId('testBtn').addEventListener('click', onTestBtnClicked, false);
}
function onTestBtnClicked(e)
{
var jsvar = 'some arbitrary text';
var url = 'phpVarTest.php?phpvar='+jsvar;
myAjaxGet(url, onAjaxDone);
}
function onAjaxDone(ajaxObj)
{
byId('outputDiv').innerText = ajaxObj.response;
}
</script>
<style>
</style>
</head>
<body>
<button id='testBtn'>Initiate ajax request</button>
<div id='outputDiv'></div>
</body>
</html>
phpVarTest.php
// server side script
<?php
echo '<?xml version="1.0" encoding = "UTF-8" standalone = "yes" ?>';
$phpvar;
$phpvar = $_GET['phpvar'];
echo "new phpvar value = ".$phpvar;
?>
output
// server side script
<?xml version="1.0" encoding = "UTF-8" standalone = "yes" ?>new phpvar value = some arbitrary text
Note: you should place the comment in the php file inside of the php tags - otherwise, you'll see it in the output, as shown above.
I have to send a name and a link from client side to the server. I thought of using AJAX called by Javascript to do this.
This is what I mean. I wished to make an ajax request to a file called abc.php with parameters :-
1. http://thumbs2.ebaystatic.com/m/m7dFgOtLUUUSpktHRspjhXw/140.jpg
2. Apple iPod touch, 3rd generation, 32GB
To begin with, I encoded the URL and tried to send it. But the server says status Forbidden
Any solution to this ?
UPDATE ::
It end up calling to
http://abc.com/addToWishlist.php?rand=506075547542422&image=http://thumbs1.ebaystatic.com/m/mO64jQrMqam2jde9aKiXC9A/140.jpg&prod=Flat%20USB%20Data%20Sync%20Charging%20Charger%20Cable%20Apple%20iPhone%204G%204S%20iPod%20Touch%20Nano
Javascript Code ::
function addToWishlist(num) {
var myurl = "addToWishlist.php";
var myurl1 = myurl;
myRand = parseInt(Math.random()*999999999999999);
var rand = "?rand="+myRand ;
var modurl = myurl1+ rand + "&image=" + encodeURI(storeArray[num][1]) + "&prod=" + encodeURI(storeArray[num][0]);
httpq2.open("GET", modurl, true);
httpq2.onreadystatechange = useHttpResponseq2;
httpq2.send(null);
}
function useHttpResponseq2() {
if (httpq2.readyState == 4) {
if(httpq2.status == 200) {
var mytext = httpq2.responseText;
document.getElementById('wish' + num).innerHTML = "Added to your wishlist.";
}
}
}
Server Code
<?php
include('/home/ankit/public_html/connect_db.php');
$image = $_GET['image'];
$prod = $_GET['prod'];
$id = $_GET['id'];
echo $prod;
echo $image;
?>
As I mentioned, its pretty basics
More Updates :
On trying to send a POST request via AJAX to the server, it says :-
Refused to set unsafe header "Content-length"
Refused to set unsafe header "Connection"
2 things.
Use encodeURIComponent() instead of encodeURI().
Here is a detailed discussion on this: When are you supposed to use escape instead of encodeURI / encodeURIComponent?
If you are new to JavaScript, use some lib to help you do the AJAX work. Like mootools, jQuery, etc.
Using a POST request solved my issue :)
function addToWishlist(num) {
var url = "trial.php";
var parameters = "prod=" + encodeURIComponent(storeArray[num][0]) + "&image=" + encodeURIComponent(storeArray[num][1]);
httpq2.open("POST", url, true);
httpq2.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpq2.onreadystatechange = function(){
if (httpq2.readyState == 4) {
if(httpq2.status == 200) {
var mytext = httpq2.responseText;
document.getElementById('wish' + num).innerHTML = "Added to your wishlist.";
}
}
};
httpq2.send(parameters);
}