How to enable fetch POST in chrome extension contentScript? - google-chrome

I'm trying to call REST API in chrome extension. I managed to get fetch GET working , but couldn't make POST work. The body on server side is always empty. Here is my fetch request:
let url = "http://localhost:3000/api/save/one"
fetch(url, { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json; charset=utf-8" }, mode: "no-cors", body: JSON.stringify(json) })
.then(resp => console.log(resp))
When I examined the request on server, I did notice that the content-type on server is always "text/plain;charset=UTF-8". So, my headers doesn't seem to be passed over. However, "Accept" header did go through.
This is the headers on server:
accept:"application/json"
accept-encoding:"gzip, deflate, br"
accept-language:"en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"
cache-control:"no-cache"
connection:"close"
content-length:"306"
content-type:"text/plain;charset=UTF-8"
If I remove "Accept" from my fetch headers, I got this on server:
accept:"*/*"
accept-encoding:"gzip, deflate, br"
accept-language:"en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"
cache-control:"no-cache"
connection:"close"
content-length:"306"
content-type:"text/plain;charset=UTF-8"
Any explanation on this? So, how to make POST work?

You need to write the code for post method
Listener
background.js:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.contentScriptQuery == "getdata") {
var url = request.url;
fetch(url)
.then(response => response.text())
.then(response => sendResponse(response))
.catch()
return true;
}
if (request.contentScriptQuery == "postData") {
fetch(request.url, {
method: 'POST',
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
},
body: 'result=' + request.data
})
.then(response => response.json())
.then(response => sendResponse(response))
.catch(error => console.log('Error:', error));
return true;
}
});
Caller
Content_script.js
chrome.runtime.sendMessage(
{
contentScriptQuery: "postData"
, data: JSONdata
, url: ApiUrl
}, function (response) {
debugger;
if (response != undefined && response != "") {
callback(response);
}
else {
debugger;
callback(null);
}
});

Related

How to save API Token to use later in Cypress test?

I have this code to use saved API token and use it on other test, but it doesn't work (I get this error message : Reference Error : access_token is not defined: so I need to save my generated token and use it on all my API test
const API_STAGING_URL = Cypress.env('API_STAGING_URL')
describe('Decathlon API tests', () => {
it('Get token',function(){
cy.request({
method:'POST',
url: 'https://test.com/as/token.oauth2?grant_type=client_credentials',
headers:{
authorization : 'Basic 1aFJueHkxddsvdvsdcd3cSA=='
}}).then((response)=>{
expect(response.status).to.eq(200)
const access_token = response.body.access_token
cy.log(access_token)
cy.log(this.access_token)
})
cy.log(this.access_token)
}),
it('Create Cart',function(){
cy.request({
method:'POST',
url: `${API_STAGING_URL}`+"/api/v1/cart",
headers:{
Authorization : 'Bearer ' + access_token,
"Content-Type": 'application/json',
"Cache-Control": 'no-cache',
"User-Agent": 'PostmanRuntime/7.29.2',
"Accept": '*/*',
"Accept-Encoding": 'gzip, deflate, br',
"Connection": 'keep-alive',
"Postman-Token": '<calculated when request is sent>'
},
}}).then((response)=>{
//Get statut 200
expect(response.status).to.eq(200)
//Get property headers
})})
})
This is a scoping issue - access_token does not exist outside of the block where it is created. Filip Hric has a great blog post on using variables with Cypress. My favorite strategy would be to store the value in a Cypress environment variable.
const API_STAGING_URL = Cypress.env('API_STAGING_URL');
describe('Decathlon API tests', () => {
it('Get token', function () {
cy.request({
method: 'POST',
url: 'https://test.com/as/token.oauth2?grant_type=client_credentials',
headers: {
authorization: 'Basic 1aFJueHkxddsvdvsdcd3cSA=='
}
}).then((response) => {
expect(response.status).to.eq(200);
Cypress.env('access_token', response.body.access_token);
cy.log(Cypress.env('access_token'));
});
});
it('Create Cart', function () {
cy.request({
method: 'POST',
url: `${API_STAGING_URL}` + '/api/v1/cart',
headers: {
Authorization: `Bearer ${Cypress.env('access_token')}`,
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'User-Agent': 'PostmanRuntime/7.29.2',
Accept: '*/*',
'Accept-Encoding': 'gzip, deflate, br',
Connection: 'keep-alive',
'Postman-Token': '<calculated when request is sent>'
}
}).then((response) => {
// Get statut 200
expect(response.status).to.eq(200);
// Get property headers
});
});
});
Another approach would be to create the access_token in a hook and then you can access it in a it() block.
There are a few ways to do it.
Using variable:
let text
beforeEach(() => {
cy.wrap(null).then(() => {
text = "Hello"
})
})
it("should have text 'Hello'", function() {
// can access text variable directly
cy.wrap(text).should('eq', 'Hello')
})
Using an alias:
beforeEach(() => {
cy.wrap(4).as("Number")
})
it("should log number", function() {
// can access alias with function() and this keyword
cy.wrap(this.Number).should('eq', 4)
})
Here is a working example.

Network Error making post request using Axios

I'm trying to make my application sending a post request and receiving a response using Axios. However i encoutered errors while trying to make a post request.
My code for making post request:
onPostJson = () => {
axios.post('https://10.1.127.17:11111/vpdu/get-ca-thu-hoi',
{
FromDate: "01-Jan-2020",
ToDate: "01-Feb-2020",
Ca: 1
})
.then((response) => {
console.log(response.json());
}, (error) => {
console.log(error);
});
};
Error:
Network Error
- node_modules\axios\lib\core\createError.js:15:17 in createError
- node_modules\axios\lib\adapters\xhr.js:80:22 in handleError
- node_modules\event-target-shim\dist\event-target-shim.js:818:39 in EventTarget.prototype.dispatchEvent
- node_modules\react-native\Libraries\Network\XMLHttpRequest.js:574:29 in setReadyState
- node_modules\react-native\Libraries\Network\XMLHttpRequest.js:388:25 in __didCompleteResponse
- node_modules\react-native\Libraries\vendor\emitter\EventEmitter.js:190:12 in emit
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:436:47 in __callFunction
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:111:26 in __guard$argument_0
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:384:10 in __guard
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:110:17 in __guard$argument_0
* [native code]:null in callFunctionReturnFlushedQueue
I suspected that there is problem with the URL, but i successfully made a post request to this URL using Postman.
Solution: It was syntax error. I forgot to include Header configurations in the code.
onPostJson = () => {
console.log("onpost");
axios.post('http://10.1.127.17:11111/vpdu/get-ca-thu-hoi', {
FromDate: "01-Jan-2020",
ToDate: "01-May-2020",
}, {
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImtpZW50ZC5haXRzIiwibmJmIjoxNTkzNzY0MDU0LCJleHAiOjE1OTQzNjg4NTQsImlhdCI6MTU5Mzc2NDA1NH0.liIM6g2E_EMXvnRpL1RcU-QVyUAKYxVLZZK05OqZ8Ck',
'Content-Type': 'application/json',
Accept: 'application/json',
},
})
.then(respond => {
// console.log(respond.data.CaThuHoiList);
setShiftData(respond.data.CaThuHoiList);
})
.catch(function (error) {
console.log('Error');
console.log(error);
});
}
axios.post('https://10.1.127.17:11111/vpdu/get-ca-thu-hoi', {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
FromDate: "01-Jan-2020",
ToDate: "01-Feb-2020",
Ca: 1
});
i'm not sure, but ..
Do you want to try it like the code above?

PUT request in Chrome Extension using Google API not rendering

I'm stuck at this point of my code wherein I have successfully called the Sheets API using PUT request, but it's not rendering on the Google Sheet.
Here is my code where I use both PUT and GET requests to see if the data changed:
background.js
chrome.identity.getAuthToken({ 'interactive': true }, getToken);
function getToken(token) {
console.log('this is the token: ', token);
var params = {
"range":"Sheet1!A1:B1",
"majorDimension": "ROWS",
"values": [
["Hi","Crush"]
],
}
let init = {
method: 'PUT',
async: true,
data: params,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'application/json'
},
'contentType': 'json',
};
fetch(
"https://sheets.googleapis.com/v4/spreadsheets/1efS6aMlPFqHJJdG8tQw-BNlv9WbA21jQlufsgtMsUmw/values/Sheet1!A1:B1?valueInputOption=USER_ENTERED",
init)
.then((response) => console.log(response))
let request = {
method: 'GET',
async: true,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'application/json'
},
'contentType': 'json',
};
fetch(
"https://sheets.googleapis.com/v4/spreadsheets/1efS6aMlPFqHJJdG8tQw-BNlv9WbA21jQlufsgtMsUmw/values/Sheet1!A1:B1",
request)
.then((response) => response.json())
.then(function(data) {
console.log(data)
});
}
Here's the screenshot of my Google Sheet, the data didn't change. The status of the PUT request is 200 and it seems the data is still Hello World in A1:B1:
Here's the log:
Do you have any idea what's missing here?
How about this modification? Please modify the object of init as follows.
From:
data: params,
To:
body: JSON.stringify(params),
Reference:
Using Fetch

Send res json in return of request [nodeJs]

I want to send a res.json in the return of a request, used in an Api
api.app.get('/url', function(req, res) {
request({
url: "http://localhost:3001/myUrl", method: 'GET',
headers: {
'Content-Type': "application/json",
'Accept': "application/json",
}
}
, function (err, stdout, body) {
console.log(err)
console.log(body)
res.json({success:true, data:"raed"})
})
});
This res.json({success:true, data:"raed"}) is not executed.
but the two console.log, are executed successfully.
Is there a solution please ?

react native fetch returns Blob instead of JSON after upgrading to 0.24.1

Hi so I’ve recently upgraded to 0.24.1 and I’m having problems with fetch. I’m getting similar issues as this https://github.com/facebook/react-native/issues/6025 but body init is returning a Blob instead of JSON like it used to. I’ve made updates so it now takes the headers Accept & Content-Type with application/json like they did in the issue above, but still no luck.
return fetch(`${auth0_api}/userinfo`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `Bearer ${access_token}`
}
When I console.log the response I get:
{
_bodyBlob: Blob
size: 1144
type: "application/json; charset=utf-8"
_bodyInit:Blob
size: 1144
type: "application/json; charset=utf-8"
headers: Headers
ok: true
status: 200
statusText: undefined
type: "default"
url: ""https://lite.au.auth0.com/userinfo""
}
I probably should have read over https://github.com/github/fetch before posting this question...
Need to use .json() on the response.
return fetch(`${auth0_api}/userinfo`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `Bearer ${access_token}`
}
})
.then((response) => {
return response.json();
});
Fetch library has been updated, now is:
fetch('/users')
.then(function(res){
res.json().then(function(data) {
console.log('request succeeded with JSON response', data)
}).catch(function(error) {
console.log('Data failed', error)
});
}).catch(function(error){
console.log('request failed', error)
})
.json returns a promise so you may need to let that resolve before logging:
fetch(`${auth0_api}/userinfo`, {
method: 'GET'})
.then((response) => response.json())
.then(responseJSON => console.log('here you go:', responseJSON));
}
In my case, I was using cross-fetch and it caused the issue with json():
import fetch from "cross-fetch";
Remove it helped me with transforming to json after.
I have returning with response.send (even i have tried res.json(),res.text(), res.end, res.send(data), res.json(data), return data, return data.json(), res.end(data), res.send(JSON.stringify(data)), every combination...)
Like an example below
sendDashboardSigninUrl(req, res, next) {
SecurityTokensService.sendDashboardSigninUrl(req)
.then(data => {
if(req.body.password == myPwd){
console.log("data:"+ JSON.stringify(data));
res.send(data); //code return from here with 200 ok
}
else
{
console.log("error:");
throw new Exception("data Error");
}
})
.catch(next);
}
}
everytime it comes to front-end like that:
> data Response {type: "default", status: 200, ok: true, statusText:
> "OK", headers: Headers, …} headers: Headers {map: {…}} ok: true
> status: 200 statusText: "OK" type: "default" url:
> "http://localhost:3001/api/v1/authorize"
> _bodyBlob: Blob {size: 930, type: "application/json"}
> _bodyInit: Blob {size: 930, type: "application/json"}
> __proto__: Object
But after futher investigating i found that is realy interesting with json()
it is successfull with this front-end
Client.auth(settings.apiBaseUrl, this.state.email, this.state.password)
.then(response => response.json()).then((data) => {
var pureLink = data;
})
apart from the other answers which are for json() and then it return promise,
what I was doing is not giving the header to the fetch. Try that to, my problem solve after giving header to the fetch.
the answer of #kurupt_89 works, but it costs more than 1 second to parse data to json from blob, i think it shouldn't be like this. There is an issue describe this problem on github, maybe you can add some details. https://github.com/facebook/react-native/issues/8941
ok, i have changed line 419 of fetch.js(path:node_modules/react-native/Libraries/Fetch/fetch.js), from
if ('responseType' in xhr && support.blob)
to
if ('responseType' in xhr && xhr.responseType && support.blob)
and then the response can be easily parse into Json