Here is a problem with "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; when I using this code in a php file, which I called from a JS (with fetch or XMLHttpRequest), the output will be the the current url of this .php file!
Example I call PHP in JS (on my wordpress site):
const item = document.querySelector('.item');
fetch('path/wp-content/themes/current_theme_directory/called.php')
.then(res => res.text())
.then(responseText => item.innerHTML = responseText);
And my called.php file contain this code:
$current_url = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
echo $current_url;
My responseText in my JS this: path/wp-content/themes/current_theme_directory/called.php
In this situation how can I get the real current url, what shows my browser also?
you can get the current url using javascript, it's in a variable called window.location.href
console.log(window.location.href); will log the current url in the console.
Technically $_SERVER['HTTP_REFERER'] will have the url that loaded the PHP, but keep in mind that info is easily edited by a crafty user.
Related
I'm trying to prompt after running a test, the download of the request, results and a brief testing summary as a text file.
Similar to what Dev Odyssey has done using the script below but with text file.
let template = `
<script type="text/javascript">
// Variable works with actual base64 string in html, not passed by variable (aka below). Otherwise Postman crashes
// window.location.href = "{{base64data}}"
// Variable works with https and file locations however...
// window.location.href = "{{webLocation}}"
// Can also download downments with the following
// window.location.href = "/Users/Someone/Downloads/my_local_doc.pdf"
window.location.href = "data:application/pdf;base64,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ZmrxUIujw7Mjw+pJLYXHd3dGovj8KCcqXyCyTL6vCn17ocft0pI3QKtp2by5ZdPmzZsufX7tk0vXruHC2TNd5851nTm7S72jfqsuqlMij5c9A8VQzsl4N+rr2a+b7mWvZjvIjW3ODutrZpvJRBaP6/SRbuOGs9fTx93F7uKCcMhFLuFy+8kv/O4CKhBFrgJ3mMJigivsLqdyUe4qd3sqRKLePn4oi3x3C26MPvr6O787Ze/+AweGHlpfunok1g4d8t7xm6f0ynNr1mXdlqyDMdKtx3hVZVT8m4eNGeAq51AJTaLJdC9NJ+OfGkPX06tvMhYP5aXTI5On5dxTvXRJXd706oWrlsxdTvRnuhSqgQplbmRzdHJlYW0KZW5kb2JqCjE5IDAgb2JqCjMzMTUKZW5kb2JqCjEgMCBvYmoKPDwgL1RpdGxlIChoZWxsb193b3JsZCkgL1Byb2R1Y2VyIChtYWNPUyBWZXJzaW9uIDEwLjE1LjcgXChCdWlsZCAxOUgyXCkgUXVhcnR6IFBERkNvbnRleHQpCi9DcmVhdG9yIChUZXh0RWRpdCkgL0NyZWF0aW9uRGF0ZSAoRDoyMDIwMTAxNDEyNDU1MFowMCcwMCcpIC9Nb2REYXRlIChEOjIwMjAxMDE0MTI0NTUwWjAwJzAwJykKPj4KZW5kb2JqCnhyZWYKMCAyMAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMTExMTAgMDAwMDAgbiAKMDAwMDAwMDI4MCAwMDAwMCBuIAowMDAwMDA2OTQwIDAwMDAwIG4gCjAwMDAwMDAwMjIgMDAwMDAgbiAKMDAwMDAwMDI2MSAwMDAwMCBuIAowMDAwMDAwMzg0IDAwMDAwIG4gCjAwMDAwMDY5MDQgMDAwMDAgbiAKMDAwMDAwNDEzMiAwMDAwMCBuIAowMDAwMDA3MDczIDAwMDAwIG4gCjAwMDAwMDA1MzMgMDAwMDAgbiAKMDAwMDAwMDU4NyAwMDAwMCBuIAowMDAwMDAwNjQwIDAwMDAwIG4gCjAwMDAwMDQxMTEgMDAwMDAgbiAKMDAwMDAwNDE2OCAwMDAwMCBuIAowMDAwMDA2ODgzIDAwMDAwIG4gCjAwMDAwMDcwMjMgMDAwMDAgbiAKMDAwMDAwNzQzMiAwMDAwMCBuIAowMDAwMDA3Njg0IDAwMDAwIG4gCjAwMDAwMTEwODkgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAyMCAvUm9vdCAxNiAwIFIgL0luZm8gMSAwIFIgL0lEIFsgPGJiOTk4ODRlNDJkNDYwYjU4ZGFmM2VlOGViMjNmNDFiPgo8YmI5OTg4NGU0MmQ0NjBiNThkYWYzZWU4ZWIyM2Y0MWI+IF0gPj4Kc3RhcnR4cmVmCjExMzE0CiUlRU9GCg=="
</script>`
pm.visualizer.set(template, {
base64data: pm.response.json()["hello_world.pdf"],
webLocation: pm.response.json().webLocation
})
Yes, I know I can use 'Send and Download' to download the response straight away but I'd like to customise the text file. Would anyone have any ideas?
Over the years on snapchat I have saved lots of photos that I would like to retrieve now, The problem is they do not make it easy to export, but luckily if you go online you can request all the data (thats great)
I can see all my photos download link and using the local HTML file if I click download it starts downloading.
Here's where the tricky part is, I have around 15,000 downloads I need to do and manually clicking each individual one will take ages, I've tried extracting all of the links through the download button and this creates lots of Urls (Great) but the problem is, if you past the url into the browser then ("Error: HTTP method GET is not supported by this URL") appears.
I've tried a multitude of different chrome extensions and none of them show the actually download, just the HTML which is on the left-hand side.
The download button is a clickable link that just starts the download in the tab. It belongs under Href A
I'm trying to figure out what the best way of bulk downloading each of these individual files is.
So, I just watched their code by downloading my own memories. They use a custom JavaScript function to download your data (a POST request with ID's in the body).
You can replicate this request, but you can also just use their method.
Open your console and use downloadMemories(<url>)
Or if you don't have the urls you can retrieve them yourself:
var links = document.getElementsByTagName("table")[0].getElementsByTagName("a");
eval(links[0].href);
UPDATE
I made a script for this:
https://github.com/ToTheMax/Snapchat-All-Memories-Downloader
Using the .json file you can download them one by one with python:
req = requests.post(url, allow_redirects=True)
response = req.text
file = requests.get(response)
Then get the correct extension and the date:
day = date.split(" ")[0]
time = date.split(" ")[1].replace(':', '-')
filename = f'memories/{day}_{time}.mp4' if type == 'VIDEO' else f'memories/{day}_{time}.jpg'
And then write it to file:
with open(filename, 'wb') as f:
f.write(file.content)
I've made a bot to download all memories.
You can download it here
It doesn't require any additional installation, just place the memories_history.json file in the same directory and run it. It skips the files that have already been downloaded.
Short answer
Download a desktop application that automates this process.
Visit downloadmysnapchatmemories.com to download the app. You can watch this tutorial guiding you through the entire process.
In short, the app reads the memories_history.json file provided by Snapchat and downloads each of the memories to your computer.
App source code
Long answer (How the app described above works)
We can iterate over each of the memories within the memories_history.json file found in your data download from Snapchat.
For each memory, we make a POST request to the URL stored as the memories Download Link. The response will be a URL to the file itself.
Then, we can make a GET request to the returned URL to retrieve the file.
Example
Here is a simplified example of fetching and downloading a single memory using NodeJS:
Let's say we have the following memory stored in fakeMemory.json:
{
"Date": "2022-01-26 12:00:00 UTC",
"Media Type": "Image",
"Download Link": "https://app.snapchat.com/..."
}
We can do the following:
// import required libraries
const fetch = require('node-fetch'); // Needed for making fetch requests
const fs = require('fs'); // Needed for writing to filesystem
const memory = JSON.parse(fs.readFileSync('fakeMemory.json'));
const response = await fetch(memory['Download Link'], { method: 'POST' });
const url = await response.text(); // returns URL to file
// We can now use the `url` to download the file.
const download = await fetch(url, { method: 'GET' });
const fileName = 'memory.jpg'; // file name we want this saved as
const fileData = download.body; // contents of the file
// Write the contents of the file to this computer using Node's file system
const fileStream = fs.createWriteStream(fileName);
fileData.pipe(fileStream);
fileStream.on('finish', () => {
console.log('memory successfully downloaded as memory.jpg');
});
I have two file inputs and button. When the button is pressed, it should send the two files to the server and wait to receive a file back (the two files processed server-side and the result is returned).
HTML
<input id='file-input1' type='file'>
<input id='file-input2' type='file'>
<button id='send-btn'>
JavaScript (Client)
var input1 = document.getElementById('file-input1');
var input2 = document.getElementById('file-input2');
var btn = document.getElementById('send-btn');
var file1 = null;
var file2 = null;
input1.addEventListener('change', () => file1 = input1.files[0]);
input2.addEventListener('change', () => file2 = input2.files[0]);
btn.addEventListener('click', () => {
if (file1 === null || file2 === null) return;
_sendfiles(file1, file2);
});
function _sendfiles(file1, file2) {
let xmlhttp = new XMLHttpRequest();
xml.open("PUT", "/process", true);
xmlhttp.send({'file1': file1, 'file2': file2});
}
JavaScript (Server)
app.put('/process', (req, res) => {
// Get files from request
// Do stuff with them to generate a third file
// Send generated file back
});
I'm not sure how to receive the files on the server-side, nor how to wait to receive the server's file on the client side. The use of third-party modules is discouraged but not completely out of the question. I'm also not married to the idea of using XMLHttpRequest().
To send files from the client I'd suggest using Fetch + FormData API for convenience:
const formData = new FormData()
formData.append('file1', file1)
formData.append('file2', file2)
fetch(`/api/companies/${id}/logo`, {
method: 'PUT',
body: formData
})
Passing FormData instance to body will automatically set Content-Type: multipart/form-data header.
On the server side I'd suggest using multer since you already use express. You can, of course, implement your own middleware to retrieve files from the request stream if you want to (I didn't do it myself so can't help much).
To receive a file on the client you can do the following (I assume you want this file to be downloaded to the user's file system):
Way #1 (simple):
In the response just send a download URL of this file. Then use this solution to create a link and trigger click event on it. The file will be downloaded by a browser.
Way #2 (not so simple):
On the server use res.sendFile method to send a file (if it's located on fs - otherwise you can send a file Buffer like this for instance).
Then on the client you have response.blob() method to access file blob.
Use a similar trick to download this blob into a file with the help of URL.createObjectURL API.
Additionally, Response API allows you to pipe the stream and do other things with it if you need to (see Streams API).
EDIT (the simplest way)
As Endless pointed out there is a much simpler way actually. I guess I spent too much time dealing with AJAX requests... 🤷‍♂️
You can just submit your HTML form by clicking on submit button, this way a browser will send POST (yeah, can't do PUT this way) request with Content-Type: multipart/form-data automatically since you have inputs with type file:
<form method='post' action='/process'>
<input name='file1' type='file'>
<input name='file2' type='file'>
<button type='submit'>Submit</button>
</form>
So no need to set any event listeners or use any JS in fact.
Then on the server use res.sendFile and add a Content-Disposition: attachment; filename="filename.jpg" header to make sure browser will download it as an attachment and not open it as a webpage.
The biggest disadvantage here is that there is no built-in convenient way in a browser to subscribe to the request's completion event. I.e. there is no success event on the form which you can listen to.
So, if you need it then a nice approach would be to send a cookie from the server along with the file.
On the client set an interval at the moment you submit the form and there check if the cookie exists. If it exists then this means the file is downloaded.
In my Vue app I receive a PDF as a blob, and want to display it using the browser's PDF viewer.
I convert it to a file, and generate an object url:
const blobFile = new File([blob], `my-file-name.pdf`, { type: 'application/pdf' })
this.invoiceUrl = window.URL.createObjectURL(blobFile)
Then I display it by setting that URL as the data attribute of an object element.
<object
:data="invoiceUrl"
type="application/pdf"
width="100%"
style="height: 100vh;">
</object>
The browser then displays the PDF using the PDF viewer. However, in Chrome, the file name that I provide (here, my-file-name.pdf) is not used: I see a hash in the title bar of the PDF viewer, and when I download the file using either 'right click -> Save as...' or the viewer's controls, it saves the file with the blob's hash (cda675a6-10af-42f3-aa68-8795aa8c377d or similar).
The viewer and file name work as I'd hoped in Firefox; it's only Chrome in which the file name is not used.
Is there any way, using native Javascript (including ES6, but no 3rd party dependencies other than Vue), to set the filename for a blob / object element in Chrome?
[edit] If it helps, the response has the following relevant headers:
Content-Type: application/pdf; charset=utf-8
Transfer-Encoding: chunked
Content-Disposition: attachment; filename*=utf-8''Invoice%2016246.pdf;
Content-Description: File Transfer
Content-Encoding: gzip
Chrome's extension seems to rely on the resource name set in the URI, i.e the file.ext in protocol://domain/path/file.ext.
So if your original URI contains that filename, the easiest might be to simply make your <object>'s data to the URI you fetched the pdf from directly, instead of going the Blob's way.
Now, there are cases it can't be done, and for these, there is a convoluted way, which might not work in future versions of Chrome, and probably not in other browsers, requiring to set up a Service Worker.
As we first said, Chrome parses the URI in search of a filename, so what we have to do, is to have an URI, with this filename, pointing to our blob:// URI.
To do so, we can use the Cache API, store our File as Request in there using our URL, and then retrieve that File from the Cache in the ServiceWorker.
Or in code,
From the main page
// register our ServiceWorker
navigator.serviceWorker.register('/sw.js')
.then(...
...
async function displayRenamedPDF(file, filename) {
// we use an hard-coded fake path
// to not interfere with legit requests
const reg_path = "/name-forcer/";
const url = reg_path + filename;
// store our File in the Cache
const store = await caches.open( "name-forcer" );
await store.put( url, new Response( file ) );
const frame = document.createElement( "iframe" );
frame.width = 400
frame.height = 500;
document.body.append( frame );
// makes the request to the File we just cached
frame.src = url;
// not needed anymore
frame.onload = (evt) => store.delete( url );
}
In the ServiceWorker sw.js
self.addEventListener('fetch', (event) => {
event.respondWith( (async () => {
const store = await caches.open("name-forcer");
const req = event.request;
const cached = await store.match( req );
return cached || fetch( req );
})() );
});
Live example (source)
Edit: This actually doesn't work in Chrome...
While it does set correctly the filename in the dialog, they seem to be unable to retrieve the file when saving it to the disk...
They don't seem to perform a Network request (and thus our SW isn't catching anything), and I don't really know where to look now.
Still this may be a good ground for future work on this.
And an other solution, I didn't took the time to check by myself, would be to run your own pdf viewer.
Mozilla has made its js based plugin pdf.js available, so from there we should be able to set the filename (even though once again I didn't dug there yet).
And as final note, Firefox is able to use the name property of a File Object a blobURI points to.
So even though it's not what OP asked for, in FF all it requires is
const file = new File([blob], filename);
const url = URL.createObjectURL(file);
object.data = url;
In Chrome, the filename is derived from the URL, so as long as you are using a blob URL, the short answer is "No, you cannot set the filename of a PDF object displayed in Chrome." You have no control over the UUID assigned to the blob URL and no way to override that as the name of the page using the object element. It is possible that inside the PDF a title is specified, and that will appear in the PDF viewer as the document name, but you still get the hash name when downloading.
This appears to be a security precaution, but I cannot say for sure.
Of course, if you have control over the URL, you can easily set the PDF filename by changing the URL.
I believe Kaiido's answer expresses, briefly, the best solution here:
"if your original URI contains that filename, the easiest might be to simply make your object's data to the URI you fetched the pdf from directly"
Especially for those coming from this similar question, it would have helped me to have more description of a specific implementation (working for pdfs) that allows the best user experience, especially when serving files that are generated on the fly.
The trick here is using a two-step process that perfectly mimics a normal link or button click. The client must (step 1) request the file be generated and stored server-side long enough for the client to (step 2) request the file itself. This requires you have some mechanism supporting unique identification of the file on disk or in a cache.
Without this process, the user will just see a blank tab while file-generation is in-progress and if it fails, then they'll just get the browser's ERR_TIMED_OUT page. Even if it succeeds, they'll have a hash in the title bar of the PDF viewer tab, and the save dialog will have the same hash as the suggested filename.
Here's the play-by-play to do better:
You can use an anchor tag or a button for the "download" or "view in browser" elements
Step 1 of 2 on the client: that element's click event can make a request for the file to be generated only (not transmitted).
Step 1 of 2 on the server: generate the file and hold on to it. Return only the filename to the client.
Step 2 of 2 on the client:
If viewing the file in the browser, use the filename returned from the generate request to then invoke window.open('view_file/<filename>?fileId=1'). That is the only way to indirectly control the name of the file as shown in the tab title and in any subsequent save dialog.
If downloading, just invoke window.open('download_file?fileId=1').
Step 2 of 2 on the server:
view_file(filename, fileId) handler just needs to serve the file using the fileId and ignore the filename parameter. In .NET, you can use a FileContentResult like File(bytes, contentType);
download_file(fileId) must set the filename via the Content-Disposition header as shown here. In .NET, that's return File(bytes, contentType, desiredFilename);
client-side download example:
download_link_clicked() {
// show spinner
ajaxGet(generate_file_url,
{},
(response) => {
// success!
// the server-side is responsible for setting the name
// of the file when it is being downloaded
window.open('download_file?fileId=1', "_blank");
// hide spinner
},
() => { // failure
// hide spinner
// proglem, notify pattern
},
null
);
client-side view example:
view_link_clicked() {
// show spinner
ajaxGet(generate_file_url,
{},
(response) => {
// success!
let filename = response.filename;
// simplest, reliable method I know of for controlling
// the filename of the PDF when viewed in the browser
window.open('view_file/'+filename+'?fileId=1')
// hide spinner
},
() => { // failure
// hide spinner
// proglem, notify pattern
},
null
);
I'm using the library pdf-lib, you can click here to learn more about the library.
I solved part of this problem by using api Document.setTitle("Some title text you want"),
Browser displayed my title correctly, but when click the download button, file name is still previous UUID. Perhaps there is other api in the library that allows you to modify download file name.
I have a large JavaScript file that I'd rather not send to the client on each request and it's too large for the browser to cache.
My thought is that I will save the file to HTML5 local storage and attempt to retrieve it. If the file is found then I'd like to link/import/export(I don't know the proper terminology) it into the same scope that a html src tag would.
My question is: how do I take a file that I've pulled from local storage and get my webpage to recognize it as a JavaScript file that was included via src tag? (minus the logic for pulling the file from storage)
My question is: how do I take a file that I've pulled from local storage and get my webpage to recognize it as a JavaScript file that was included via src tag?
Two possible ways (amongst maybe others):
create a script element, and assign your JS code as the “text content” of that element before appending it to the DOM. “Text content” in quotes here, because it is not as simple as it sounds cross-browser – see f.e. Javascript script element set inner text, Executing elements inserted with .innerHTML, or
assign your script code to the src attribute of a script element via a Data URI, data:text/javascript,… – but that approach has several disadvantages as well, also mostly in older IE (size limitation; only “non-navigable” content, meaning no scripts). But depending on your target environment that might well work. You will not necessarily need to base64 encode the script code, URL-percent-encoding via encodeURIComponent should work as well.
Take a look at this:
http://jsfiddle.net/611e96mz/1/
var tag = getId('testjs'),
a = getId('a'),
b = getId('b'),
c = getId('c'),
script;
a.addEventListener('click', function () {
localStorage.setItem('js', tag.innerHTML);
});
b.addEventListener('click', function () {
script.textContent = localStorage.getItem('js');
});
c.addEventListener('click', function () {
document.body.appendChild(script);
alertMe();
});
var script = document.createElement("script");
script.type = "text/javascript";
function getId(x) {
return document.getElementById(x);
}
You can use JSON to stringfy your file content and put it on localstorage.
var content = JSON.stringify([1, "some info"]); // '[1,"some info"]'
localStorage.setItem('fileContent', content);
// Retrieve
var content = localStorage.getItem('fileContent');
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify