Fetch HTTP Request and Navigate - Chrome - google-chrome

Here is a sample POST request which I run inside the Console window of Chrome.
fetch("https://demo.wpjobboard.net/wp-login.php", {
"headers": {
"Host": "demo.wpjobboard.net:443",
"Content-Length": "19",
"Cookie": "wpjb_transient_id=1607759726-1847; wordpress_test_cookie=WP+Cookie+check",
"Content-Type": "application/x-www-form-urlencoded"
},
"body": "log=7887&pwd=789789",
"method": "POST",
}).then(console.log);
I need to navigate and see HTML rendered results inside the chrome, not just seeing some complex results inside the console. How to achieve this?

Fetch returns promise and first what you get is streaming data from your server. You need to convert it to text or JSON after that you can use it like a normal variable.
I have moved your URL and options in separate variables in order to focus code on fetch request implementation.
const url = `https://demo.wpjobboard.net/wp-login.php`
const opts = {
headers: {
'Cookie': `wpjb_transient_id=1607759726-1847; wordpress_test_cookie=WP+Cookie+check`,
'Content-Type': `application/x-www-form-urlencoded`
},
body: `log=7887&pwd=789789`,
method: `POST`,
}
fetch(url, opts)
.then(res => res.text()) // if you get json as response use: res.json()
.then(html => {
const win = window.open(``, `_blank`)
win.document.body.innerHTML = html
win.focus()
})

Related

Slack API call to postMessage not working

I'm just trying to make a simple postMessage call from a google apps script with an image attached, but I get the following response:
"{"ok":false,"error":"invalid_arg_name"}"
Here is the function that creates the payload:
function getPostMessagePayload(fileUrl) {
var content = {
"channel":"#data-vis",
"token": ACCESS_TOKEN,
"text":"Chart update:",
"attachments": [
{
"title": "Chart",
"fallback": "Fallback",
"text": "Testing chart",
"image_url": fileUrl
}
]
};
return content;
}
And here is where I make the request:
var POST_MESSAGE_ENDPOINT = 'https://slack.com/api/chat.postMessage';
function performPostMessage(payload) {
var res = UrlFetchApp.fetch(
POST_MESSAGE_ENDPOINT,
{
method: "post",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
}).getContentText();
return res;
}
It's impossible to tell what the actual problem is. I've tried making my token obviously incorrect, the URL obviously incorrect, and deleting/adding random args and it gives the same response every time.
When I use the webhook to do this rather than the API, it works fine.
My app has the following permissions in Slack:
chat:write:bot
incoming-webhook
Problem
You are sending a JSON object as payload with your POST request, whilst the contentType parameter of the fetch() method is defaulted to application/x-www-form-urlencoded.
Solution 1
In addition to JSON.stringify(), to ensure the payload is sent correctly, wrap it in an encodeURIComponent() built-in function. If the issue persists, continue to solution 2.
Update to solution 1
Nearly forgot how fetch() method treats objects passed to payload with default x-www-form-urlencoded content type. Remove the JSON.stringify() entirely (and add encodeURI() / encodeURIComponent() if needed).
Solution 2
Slack API supports application/json content type of POST requests. In your case it might be easier to send the request with contentType parameter set to application.json (note that you will have to move authorization from payload to headers):
//fetch part;
var res = UrlFetchApp.fetch(
POST_MESSAGE_ENDPOINT,
{
method : 'post',
contentType : 'application/json',
headers : {
Authorization : 'Bearer ' + ACCESS_TOKEN
},
payload : JSON.stringify(payload),
muteHttpExceptions : true,
})
//payload part;
var payload = {
"channel" : "#data-vis",
"text" : "Chart update:",
"attachments" : [
{
"title" : "Chart",
"fallback" : "Fallback",
"text" : "Testing chart",
"image_url" : fileUrl
}
]
};
Useful links
fetch() method reference;
postMessage method reference (Slack API);

LinkedIn not reading JSON request

Trying to 'share' on LinkedIn: https://developer.linkedin.com/docs/share-on-linkedin
Which is basically a POST to 'https://api.linkedin.com/v1/people/~/shares?format=json'
in its simplest form is with json:
{
"comment": "Check out developer.linkedin.com! http://linkd.in/1FC2PyG",
"visibility": {
"code": "anyone"
}
}
This requires setting http headers:
Content-Type: application/json
x-li-format: json
I'm trying to do this using OAuth.io, but LinkedIn seems to be still reading the body in XML.
See my example here: https://jsfiddle.net/Lv3jtpkb/2/
I get the following error from it:
Invalid xml {Element 'share#http://api.linkedin.com/v1' with element-only content type cannot have text content.}
I have checked if from OAuth.io server to LinkedIn API endpoint the headers specified here at frontend were somehow altered and can confirm that they have not been.
You're almost there. There are 2 errors.
Your data are formatted as a JS object. The method you're using doesn't seem to be converting the object to JSON automatically.
This line of code isn't doing anything, and is causing exceptions:
.then(user => { console.log("next:",user) })
Remove it.
Working code snippet:
$('#linkedin-button').on('click', function() {
// Initialize with your OAuth.io app public key
OAuth.initialize('A5oDtHv-oUEVlR7q7hDolXxC7RE');
alert('init');
OAuth.popup('linkedin2').then(linkedin => {
alert('logged in');
linkedin.post({
url: "/v1/people/~/shares?format=json",
data: JSON.stringify({
"comment": "Hello world!",
"visibility": {
"code": "anyone"
}
}),
headers: {
"x-li-format": "json",
"Content-Type": "application/json"
}
}).then(data => {
console.log("success:", data);
}).fail(err => { console.log("err:",err) });
})
})
Success in console:

How to send JSON in a POST request with NodeJS

I'm trying to send a POST request to an endpoint which accepts JSON and it doesn't work. Do I have to send any specific parameter in order to let the network know it is encoded as JSON?
Here is the simple request I've so far:
var request = require('request')
var cookie = '**Here the cookie copied from the Network tab from the Chrome Dev Tools Bar**'
var UA = '**Here the UA copied from the Network tab from the Chrome Dev Tools Bar**'
var JSONformData = {"jsonrpc":"2.0","method":"LMT_split_into_sentences","params":{"texts":["Text"],"lang":{"lang_user_selected":"auto","user_preferred_langs":["EN","ES"]}},"id":8}
var URL = 'https://www.deepl.com/jsonrpc'
request.cookie(cookie)
request.post({
url: URL,
headers: {
'User-Agent': UA
},
form: JSONformData
}, function(error, response, body) {
console.log(response)
}
)
If you are sending JSON data then you don't need to specify the form, instead specify the json for data in the options object:
request.post({
url: URL,
headers: {
'User-Agent': UA
},
json: JSONformData
}, function(error, response, body) {
console.log(response)
})

How to return a JSON object from an Azure Function with Node.js

With Azure Functions, what do you need to do to return a JSON object in the body from a function written in node.js? I can easily return a string, but when I try to return a json object as shown below I appear to have nothing returned.
context.res = {
body: jsonData,
contentType: 'application/json'
};
Based on my recent testing (March 2017). You have to explicitly add content type to response headers to get json back otherwise data shows-up as XML in browser.
"Content-Type":"application/json"
res = {
status: 200, /* Defaults to 200 */
body: {message: "Hello " + (req.query.name || req.body.name)},
headers: {
'Content-Type': 'application/json'
}
};
Full Sample below:
module.exports = function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
context.log(context);
if (req.query.name || (req.body && req.body.name)) {
res = {
// status: 200, /* Defaults to 200 */
body: {message: "Hello " + (req.query.name || req.body.name)},
headers: {
'Content-Type': 'application/json'
}
};
}
else {
res = {
status: 400,
body: "Please pass a name on the query string or in the request body"
};
}
context.done(null, res);
};
If your data is a JS object, then this should just work, e.g.
module.exports = function(context, req) {
context.res = {
body: { name: "Azure Functions" }
};
context.done();
};
This will return an application/json response.
If instead you have your data in a json string, you can have:
module.exports = function(context, req) {
context.res = {
body: '{ "name": "Azure Functions" }'
};
context.done();
};
Which will return an application/json response because it sniffs that it is valid json.
module.exports = function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
if (req.query.name || (req.body && req.body.name)) {
context.res = {
// status: 200, /* Defaults to 200 */
body: {"data":"Hello"},
headers: {
'Content-Type': 'application/json'
}
};
}
else {
// res = {
// status: 400,
// body: "Please pass a name on the query string or in the request body"
// };
}
context.done(null,res);
I would like to add one more point. Apart from making the body: a JSON object, the request should also contain proper headers telling server what content type we are interested in. I could see that same Azure function when just invoked via browser using URL gives XML response, but when invoking from script or tools like Postman it gives JSON.
I feel like the answer has been given but it hasn't been clearly presented so I thought I'd answer as well in case it will help anyone coming behind me. I too have created a function that most definitely returns a Javascript object but if I copy and paste the URL in the Azure Function UI and just open a new tab in Chrome and try to view the output, I actually get back an XML document that tells me there's an error (not surprising there's an error as many characters in the Javascript would have blown up the XML). So, as others have mentioned, the key is sending the appropriate headers with your request. When you copy/paste the URL into your browser, the browser is sending a request header that looks similar to this:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
When that happens, you see the XML return as described in this link:
https://github.com/strongloop/strong-remoting/issues/118
In order to get around this problem and see what the data would look like with a JSON request, either use a utility like Postman:
https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en
Accept: application/json
Or use a CURL command and pass in the proper Accept header.
As you can see in the screenshot above, when I provided the proper header, I get back the JSON response I would expect.
You can also use JSON.stringify() to make a valid json string out of your js-object:
jsonData = { value: "test" }:
context.res = {
body: JSON.stringify(jsonData)
};

using Parse.Cloud.httpRequest I am unable to set correct header for AWS request?

On Parse.com, from CloudCode I need to send httpRequest to AWS (Kinesis); they are signed and it all work when sent from the browser side (extension). I have tried the following header content-type in my request in CloudCode:
"content-type": "application/json"
AWS refused it: {"Output":{"__type":"com.amazon.coral.service#UnknownOperationException","message":null},"Version":"1.0"}
"content-type": "application/x-amz-json-1.1"
parse.cloud.httprequest refused it: Result: Uncaught Error: Don't know how to convert httpRequest body Object to application/x-amz-json-1.1. To send raw bytes, please assign httpRequest body to a Buffer object containing your data.
"content-type": "application/x-www-form-urlencoded"
AWS refused it: Request failed with response code 403
AWS documentation mentions the "application/x-amz-json-1.1" content-type everywhere and I cannot see any alternative. So, I'm assuming that's the way to go, so:
How can I ask Parse.Cloud.httpRequest to send the request with this X-AMZ-JSON header but use "application/json" ‘internally’?
update: I tried to use "http" and "xmlhttp" modules taken from Node; but none of them worked—I'm happy to try any suggestions you may have.
update: this is the actual request I'm making
Parse.Cloud.httpRequest({
method: 'POST',
url: awsKinesisUrl,
headers: {
"Authorization": concat_string,
"action": "PutRecord",
"acl": "public-read",
'awsaccesskeyid': "__XXX__",
"content-type": "application/x-amz-json-1.1",
"dategenerated": date_generated+"",
"region": "eu-west-1",
"version": "2013-12-02",
"X-Amz-Date": date_generated_TZ+"",
"X-Amz-Target": "Kinesis_20131202.PutRecords"
},
body: {
body: http_req_body
},
success: function(httpResponse) {
var message = httpResponse.text;
res.render('json', {message: '{response:\''+message+'\'}' });
},
error: function(httpResponse) {
var message = httpResponse.status;
res.render('json', {message: '{response:\''+message+'\'}' });
}
});
Check out the blog post on sending raw bytes through httpRequest: http://blog.parse.com/2013/04/04/sending-bytes-from-cloud-code/
If http_req_body is a JS object, then you can use the following method call:
// Require can go at the global scope
var Buffer = require('buffer').Buffer;
Parse.Cloud.httpRequest({
method: 'POST',
url: awsKinesisUrl,
headers: {
"Authorization": concat_string,
"action": "PutRecord",
"acl": "public-read",
'awsaccesskeyid': "__XXX__",
"content-type": "application/x-amz-json-1.1",
"dategenerated": date_generated+"",
"region": "eu-west-1",
"version": "2013-12-02",
"X-Amz-Date": date_generated_TZ+"",
"X-Amz-Target": "Kinesis_20131202.PutRecords"
},
body: new Buffer(JSON.stringify(http_req_body))
}).always(function(httpResponse) {
var message = httpResponse.text;
res.render('json', {message: '{response:\''+message+'\'}' });
});
I also took the liberty of replacing your success/error callback with the newer Promise technique (http://blog.parse.com/2013/01/29/whats-so-great-about-javascript-promises/). This not only lets you manage several API requests more easily but let you consolidate the handlers you were rewriting for both success and error conditions.