I have an existing PHP code that is doing a curl request to a 3rd-party PHP server.
The 3rd-party server returns a GZIP string.
In PHP, I can use gzdecode to decode the gzip string.
How can I do it in NodeJS/Javascript? I tried using decompress-response with no avail.
Also tried using got instead of request, enabled auto-decompress, also doesn't work.
Edit: Also tried zlib and pako, also doesn't work.
Sample Code [ PHP ]
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $params,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 3000000,
CURLOPT_ENCODING => '',
CURLOPT_CUSTOMREQUEST => "GET",
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo false;
} else {
$response = gzdecode($response);
echo $response;
}
This is the solution that works for me.
I used got instead of axios because I can't get it to work there.
I set my request options:
const requestOptions = {
encoding: null, // this is important
headers: {
"Accept-Encoding": "gzip",
}
...
};
Don't forget that encoding: null line, because without that, the response will be automatically converted to a string. ( We need a buffer to make this work )
Then I created a function like this to handle my request:
const zlib = require("zlib");
async function performRequest(url, options) {
try {
const response = await got(url, options);
if (response.headers["content-encoding"] === "gzip") {
const body = response.body;
try {
const dezziped = zlib.gunzipSync(response.body);
response.body = JSON.parse(dezziped.toString());
} catch (error) {
response.body = body;
}
}
return response.body;
} catch (error) {
return error;
}
}
Note: This is a synchronous operation, you can use gunzip instead if you want to do the async way.
Related
I'm trying to upload a file in my local webserver but I'm running into an error that I don't fully understand. I think there might be an issue with my PHP script.
Here is my code :
JS :
addImageBlobHook: (blob, callback) => {
let formData = new FormData();
// file in a 'multipart/form-data' request
formData.append(0, blob, blob.name);
fetch('upload', {
method: 'POST',
body: formData
}).then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Server or network error');
}).then(response => {
if (!response.success) {
throw new Error('Validation error');
}
callback(response.data.url, 'alt text');
}).catch(error => {
console.log(error);
})
}
PHP :
<?php
if(isset($_FILES['file']['name'])){
// file name
$filename = $_FILES['file']['name'];
// Location
$location = 'upload/'.$filename;
// file extension
$file_extension = pathinfo($location, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
// Valid extensions
$valid_ext = array("jpg","png","jpeg");
$response = 0;
if(in_array($file_extension,$valid_ext)){
// Upload file
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){
$response = 1;
}
}
echo $response;
exit;
}
else echo json_encode(2);
I'm getting the following error :
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
on line 85, which is in my code the console.log(error); in the JS file.
EDIT:
Replacing isset($_FILES(['file.....) with just isset($_FILES) allow to enter the 'if' and make a vardump, like so :
if(isset($_FILES)){
var_dump($_FILES);
Which returns :
C:\wamp64\www\toast\upload.php:5:
array (size=1)
0 =>
array (size=5)
'name' => string 'Beer_mug_transparent.png' (length=24)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 3
'size' => int 0
You are just echo the response. Which does not give proper response. Please see updated php code.
<?php
if(isset($_FILES['file']['name'])){
// file name
$filename = $_FILES['file']['name'];
// Location
$location = 'upload/'.$filename;
// file extension
$file_extension = pathinfo($location, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
// Valid extensions
$valid_ext = array("jpg","png","jpeg");
$response = 0;
if(in_array($file_extension,$valid_ext)){
// Upload file
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){
$response = 1;
}
}
echo json_encode($response);
exit;
}
So i got this POST json method here, but can't understand how to get my json data
It's packed in BLOB which is packed in FormData
How to receive such POST in php? (and convert this FormData(Blob) back to json?)
JS
const data = new FormData();
const jsonBlob = new Blob([JSON.stringify(myJSON)], {type: "application/json"});
data.append("data", jsonBlob);
fetch(website,{
method: "POST",
body: data,
}).then(resp=>{
if(!resp.ok){
const err = new Error("Error response");
err.resp = resp;
throw err;
}
console.log("OK");
}).catch(err =>{
console.error(err);
})
I'm big noobo, so i can't even receive it
Seems like it works differently with fetch()
PHP
if(isset($_POST['data'])){
}
The simpliest way to send a JSON to server is to simply send it as the POST request body. There is no need to wrap it like a file. For example,
var myJSON = {
hello: 'world',
foo: 'bar',
};
fetch(website, {
method: "POST",
body: JSON.stringify(myJSON),
})
On server side, your message will be readable through the "php://input" stream. You can read it like an ordinary file:
$request_raw = file_get_contents('php://input');
$json_object = json_decode($request_raw);
You can save the below code as a PHP file and test it yourself. On load, it would send itself another POST reqeust, parse it as key-value pairs, return it to your browser and show it:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$request_raw = file_get_contents('php://input');
$request = json_decode($request_raw);
foreach ($request as $key => $value) {
echo "{$key}: {$value}\n";
}
exit;
}
?>
<div id="result"></div>
<script>
var myJSON = {
hello: 'world',
foo: 'bar',
};
const data = new FormData();
fetch(document.location.href, {
method: "POST",
body: JSON.stringify(myJSON),
}).then(resp => {
if(!resp.ok){
const err = new Error("Error response");
err.resp = resp;
throw err;
}
console.log("OK");
return resp.text();
}).catch(err =>{
console.error(err);
}).then(body => {
document.getElementById('result').innerText = body;
});
</script>
I'm working on a project where I have an async function in JS calling to a PHP function, but for some reason it keeps throwing my error function even though I feel I have the syntax correct.
Here is the JS:
async function UpdateBlog() {
var test = "test";
const settings = {
method: 'POST',
body: JSON.stringify({
blog: test
}),
headers: {
'Content-Type': 'application/json',
}
};
var thisurl = baseurl;
const response = await fetch(thisurl, settings);
document.getElementById("scratch").innerHTML = await response.json();
}
And here is what is catching it in PHP
if ($_SERVER["REQUEST_METHOD"] == "POST"){
if(isset($_POST["blog"])){
UpdateBlog($_POST["blog"]);
}
else {
RequestFail();
}
function RequestFail(){
http_response_code(404);
header('Content-Type: application/json');
echo json_encode(false);
}
I have tested the "UpdateBlog" PHP function as a GET and it works, so that's not the issue
Edit: Figured out the first if... statement is being triggered, but it seems that $_POST["blog"] is showing up as empty
If fetch is a "thenable" function, it may be better to use
const result = ''
fetch(thisurl, settings).then(
(result) => {response = result;}
)
The guy responsible for API requests is gone for the week, so nothing can be done on server side.
fetch("https://url.com/api/login/", {
method: "post",
headers: {
// 'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: JSON.stringify({
username: "test#mail.com",
password: "123"
})
}).then(function (response) {
return response.json();
}).then(function (myJson) {
console.log(myJson);
});
It works on Postman, but as I heard, Postman doesn't follow the same security as browsers, therefore this isn't an issue for Postman. But I doubt this is the case, as the authors php-solution works fine.
This is an example of php-solution that works (He wrote it):
function login($username, $password) {
$curl = curl_init(); curl_setopt_array($curl, array(
CURLOPT_URL => "https://url.com/api/login/",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_MAXREDIRS => 10,
CURLOPT_POSTFIELDS => "username=".$username."&password=".$password,
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application/x-www-form-urlencoded"),
));
$response = curl_exec($curl);
curl_close($curl);
$authdata = json_decode($response);
if ($authdata -> success) {
//success
return true;
} else {
//fail
return false;
}
}
What's missing in my code? How can I make it work like his php solution. (Have no experience in php).
Any help is much appreciated.
EDIT:
What worked on Postman:
Raw json format in Body.
Adding values as Key and Value in x-www-form-urlencoded
To solve this error you can do 3 things:
Add your origin server side.
Run your javascript on the same domain.
Check this answer for disabling same origin policy in chrome. This will allow you to test your code until the guy responsible for de API returns.
Here is my curl command is there anyway to execute this command using ajax
curl -X POST -u "CONVERSATION_USERNAME":"CONVERSATION_PASSWORD" -H "Content-Type:application/json" -d "{\"input\": {\"text\":\" \"}}" "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11"
This should work.
$.ajax({
url: "https://conversation_username:conversation_password#gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11",
method: "POST",
headers: {
"Content-Type": "application/json"
},
data: {
input: {
text: " "
}
}
})
done(function(data) {
// handle success response
})
.fail(function(err) {
// handle error response
});
http://api.jquery.com/jquery.ajax/
edit - updated to handle success and error responses using promises.
Create a php file, put that command inside that file, return from it whatever you need from the curl response and call this php file via ajax.
file ajax_curl.php
<?php
//do your curl call here
//curl -X POST -u "CONVERSATION_USERNAME":"CONVERSATION_PASSWORD" -H "Content-Type:application/json" -d "{\"input\": {\"text\":\" \"}}" "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11"
//see http://php.net/manual/en/curl.examples-basic.php
//do a return like so if $url is you url
$defaults = array(
CURLOPT_URL => $url,
your_other_params => go_here,
CURLOPT_RETURNTRANSFER => 1
);
$ch = curl_init();
curl_setopt_array($ch, $defaults);
$result= curl_exec($ch);
if( ! $result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
curl_close($ch);
echo json_encode($result);
?>
your calling js looks like
$.post( "ajax_curl.php", { passed_data: "pass_whatever_you_need" }, function( data ) {
console.log( data );
}, "json");
'data' now contains a json with the response from your curl call
Create a PHP file.here file name is chat.php
<?php
if(isset($_POST['conversation'])) {
$data = array("input"=>array("text"=>$_POST["conversation"]));
$url = "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/a9379972-d820-4cdf-b1cb-ad0af898a534/message?version=2016-07-11";
$ch = curl_init($url);
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_USERPWD => "username:password",
CURLOPT_HTTPHEADER => array("Content-Type:application/json"),
CURLOPT_POSTFIELDS => json_encode($data),
));
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response));
}
?>
and call this by using Ajax
var xhr = new XMLHttpRequest();
//xhr.open('get', 'chat.php');
xhr.open("GET", "chat.php?data=" + data to be pass, false);
// Track the state changes of the request.
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
//alert(xhr.responseText);
talking = true;
botMessage=xhr.responseText;// 'This is the returned text.'
} else {
// console.log('Error: ' + xhr.status); // An error occurred during the request.
alert ('Error: ' + xhr.status);
}
}
};
// Send the request to send-ajax-data.php
xhr.send();