0

I have a .js file hosted on domain1.com, but for this to work correctly I need to add a PHP code at the beginning. The reason for this is to bypass some restriction on Safari for my script and it requires me to create a session. The PHP code creates a session through a url to domain2.com. There is no browser redirection or anything, the user stays in the domain1.com. I want to have a single .js file in domain1.com so maybe an AJAX solution is what I need. Here it is:

<?php session_start(); if (!isset($_SESSION['isIFrameSessionStarted'])) { $_SESSION['isIFrameSessionStarted'] = 1; $redirect = rawurlencode('http://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"); header('Location: domain2.com/start-session.php?redirect=' . $redirect); exit; } ?> 

The start-session.php file is hosted on domain2.com does not need any changes, it contains this:

<?php session_start(); // create the session cookie $redirect = rawurldecode($_GET['redirect']); header('Location: ' . $redirect); // redirect back to domain exit; ?> 
12
  • 1
    What's the problem? Put the PHP code into the PHP file. I must be missing something because it seems trivial... Commented Jun 3, 2015 at 7:52
  • What is it you want to do? Redirect to another page? If you call this with AJAX you won't get redirected. You probably need to pass the URL you want to redirect to to JavaScript and do the redirection there. Commented Jun 3, 2015 at 8:07
  • @putvande Hi, can you show me how please? Commented Jun 3, 2015 at 9:17
  • @pid the thing is that I want to have a single js file. and i can't put PHP into that Commented Jun 3, 2015 at 9:18
  • 3
    Could you clarify what you're trying to do, @Xalloumkkelos? Are you trying to import a .js file from domain 1 to domain 2? Run a script from domain 1 through domain 2? Access data from domain 1 not available on domain 2? Commented Jun 9, 2015 at 14:44

6 Answers 6

7
+100

Let me combine what you requested in comments:

I have a .js file hosted on domain1 ... I want to have a single js file and I can't put PHP into that ... the whole purpose of this is for domain1 to not have any php code or php file. ... The reason is because I want it cross-domain and the session to be created from domain2.

It sounds like your issue might be related to the Safari iFrame session cookie problem, especially because you have if (!isset($_SESSION['isIFrameSessionStarted'])) in one of your code blocks. I will continue with this assumption.

Summary of the problem for other readers:

Upon embeding an IFrame from one domain into a website of a different domain, you will quickly realise that Internet Explorer and Safari are blocking the cookies (and thus the session variables) of the website inside the IFrame (ref).


Attempted solutions that didn't pan out:


My solution:

Essentially, PHP session "hijacking". It works surprisingly well where the above solutions failed. This is the essential solution. Please do any security enhancements* and URL-prettifying you like. Basically, we retrieve the PHP session ID through redirects and pass this to the iframe. Instructions are in the comments.

In your domainA.com head place this:

<script src="session.js"></script> 

session.js (on domainA.com):

// Location of the domain B session starter var sessionScriptURL = "http://domainB.com/start-session.php"; var refQSparam = "phpsessionid"; // Check if we have the phpsessionid in the query string var phpsessionid = getParameterByName(refQSparam); if(phpsessionid === null) { // Not in the query string, so check if we have it in session storage var sessionStore = sessionStorage.getItem(refQSparam); if(sessionStore === null) { // We have no session storage of the PHP session ID either, redirect to get it top.location = sessionScriptURL + "?redirect=" + encodeURIComponent(self.location.href); } else { // phpsessionid was found in session storage. Retrive it phpsessionid = sessionStore; } } else { // Save the phpsessionid to session storage for browser refresh sessionStorage.setItem(refQSparam, phpsessionid); // Optional: Redirect again to remove the extra query string data } // Helper to get QS values function getParameterByName(name) { return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null; } 

session-starter.php (on domainB.com):

<?php session_start(); // create the session cookie $redirect = rawurldecode($_GET['redirect']); // redirect back with the php session ID // Optional: encode this information $href = $redirect . '?phpsessionid=' . session_id(); header('Location: ' . $href); exit; 

HTML (in the body, on domainA.com):

Append PHP session information to the iframe src.

<script> document.write('<iframe src="http://domainB.com/embedded-script.php?phpsessionid='+phpsessionid+'"></iframe>'); </script> 

embedded-script.php (on domainB.com, in an iframe):

<?php // Use the phpsessionid passed in $phpsessionid = rawurldecode($_GET['phpsessionid']); // REF: http://php.net/manual/en/function.session-id.php function session_valid_id($session_id) { return preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $session_id) > 0; } // Check that this is potentially a valid session ID if(session_valid_id($phpsessionid)) { // Set the session to the one obtained in session-start.php session_id($phpsessionid); } session_start(); // Only call this after session_id()! // Rest of your code 

*Considerations:

  1. Don't actually use document.write, use jQuery or document selectors.

  2. Encode the PHP session ID

  3. Perform another redirect back to the base URL of domainA.com to remove the ?phpsessionid= in the URL for a cleaner look.

  4. If you decide to call session-starter.php with AJAX instead, you will get a new PHP session ID every time for the same reason. The iframe will successfully use this session ID, but if you open a new page to domainB.com, the session will yet again be different.

Sign up to request clarification or add additional context in comments.

2 Comments

why didn't you decide to implement an AJAX solution but took this approach?
@Daniel Two reasons: 1) In the original question the OP didn't even talk about AJAX, and 2) with this method the OP can open a new window to domainB's page and the session will still be the same.
4

If you want to run PHP within a file extended with .js, you can do this by telling your apache web server. Add the following directive to the .htaccess or directly to the apache config:

AddType application/x-httpd-php .js 

After this is done, your server will run the included PHP code as soon as the file is requested from the server.


Update:

If you want to use sessions with JavaScript, you can do this with an AJAX solution. For this implement a web service on the server which should store the session values. Programming language for implementation can be PHP or another one which can be run by the web server. Request the web service with JavaScript. Here is an answer with an example.

2 Comments

I know this but I do not want to alter the settings. An ajax solution would be great.
@Xalloumokkelos Well, then you might reformulate your question and ask for an AJAX solution.
3

If you want to redirect in Javascript, you can't use a PHP redirect which you have called from AJAX. You can pass the URL you create in PHP and send it back to JavaScript and do the redirect from there. You can do something like:

PHP:

session_start(); if (!isset($_SESSION['isIFrameSessionStarted'])) { $_SESSION['isIFrameSessionStarted'] = 1; $redirect = rawurlencode('http://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"); echo json_encode(array('url' => $redirect)); } 

JavaScript:

$.get('phpfile', function(result) { if (!result) return; var data = JSON.parse(result); window.location.href = decodeURIComponent(data.url); }); 

3 Comments

Hi, thank you for your answer, I will try it. The code does not take me to a new page, it just created a new session required to work. I will try it and let you know!
Maybe $_SESSION['isIFrameSessionStarted'] was already set and you didn't get anything back?
Hello, I have updated my question and added +200 bounty
2

Don't know what you're trying to achieve exactly but let's say you want to go from php to js and back to php you could trying something like this:

Solution 1: Using XMLHttpRequest

In PHP (domain1.com):

<?php $parameter = ""; //If you'll like to add a parameter here echo "<script type='text/javascript'>window.addEventListener('DOMContentLoaded',". "function () { goToJS('$paramter');});</script>"; ?> 

In JS:

window.goToJS = function (parameter) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState === 4 && xmlhttp.status === 200) { //You can redirect back to a php file here document.location.href = "domain1.com"; //You can view feedback from that php file you sent the stuff to here - just for testing alert("feedback" + xmlhttp.responseText); } } xmlhttp.open('GET', 'http://domain2.com/start-session.php?q=' + parameter, true); xmlhttp.send(); } 

Not sure about your redirect links and stuff but yeah this should pretty much work. Did something similar a while back

Solution 2: Using ajax

Using ajax you could have a JS script as follows. (type could be POST or GET, Used an example where you sent some json to the php file. Can change the data sent if you properly describe to me what you wish to send. Alternatively could be null also

In JS:

function init_() { $.ajax({ type: 'POST', url: 'http://domain2.com/start-session.php', data: {json: JSON.stringify(selectedEvent)}, dataType: 'json' }).done(function (data) { console.log('done'); console.log(data); }).fail(function (data) { console.log('fail'); console.log(data); }); } 

In PHP: Let's say you sent a javascript json to PHP. You could use it in PHP as follows:

<?php $status_header = 'HTTP/1.1 ' . 200 . ' ' . 'OK'; header($status_header); header('Content-type: text/javascript'); $json = json_decode($_POST['json']); //Do whatever you want with the json or data sent echo "This is the returned data"; //Echo returned data back to JS or wherever ?> 

4 Comments

Hi, thank you but I can not follow the instructions on this. what should I add in redirect.php for example? Is it the code of the first block ?
@Xalloumokkelos Yes the first block of code is your supposed domain1.com which calls the js function in the second block. In the second block the js would do whatever action in the xmlhttp.open(); bit. Then the redirect.php here should be your domain1.com. Do you follow now? Edited the answer
But the whole purpose of this is to domain1 to not have any php code or php file...
@Xalloumokkelos doesn't have to have one actually. Your question wasn't quite clear at first that's why I just put it up there. The echoed javascript can be all you put there. Don't necessarily need to wrap it in php tags if your page isn't php. I hope you follow. Do you? Updated my answer to add Ajax since you changed your question slightly
2

why don't just use script directly (if you put this script on top of file it will wait the script to finish creating session in domain2 anyway. (I guess you have iframe in domain1 that call to domain2?)

<script src="http://domain2.com/start-session.php"></script> 

1 Comment

This unfortunately won't work. I thought of this too and vetted it.
2

USe jquery and jqxhr object for this request, no need send browser to second server, from domain1 you can request to browser load page to init session, and your client never see that.

//include jquery min library and do next code $(document).ready(function (){ var jqxhr = $.get( "http://domain2.com/start-session.php", function() { alert( "success" ); //some action for success }) .done(function() { alert( "second success" ); //when all is done (success done) }) .fail(function() { alert( "error" ); //some action for error }) .always(function() { alert( "finished" ); //some end action for anycase }); }); 

you can delete .done function, .fail function, and always function as you wish. NOTE: ready function is to make sure, that domain1 page completely load, and then run script.

reference https://api.jquery.com/jquery.get/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.