I am trying to communicate with a 3rd party API. I wrote the API in python. I want to update the name column in the database from the Wix web page using a user form and text box. The database updates and all of the endpoints are responsive using postman to test. I think the problem resides in my JavaScript on the Wix end.
I modeled the JavaScript from the Wix example at:
https://support.wix.com/en/article/calling-server-side-code-from-the-front-end-with-web-modules
I have a back end module called placeOrder stored in orderplaced.jsw that should post the variable 'name' to the api.
import { fetch } from 'wix-fetch';
// wix-fetch is the API we provide to make https calls in the backend
export function placeOrder(name) {
return fetch("https://reliableeparts.pythonanywhere.com/user", {
method: 'post',
name: JSON.stringify({ name })
}).then(function (response) {
if (response.status >= 200 && response.status < 300){
console.log(JSON.stringify({ name }))
return response.text();}
console.log(Error(response.statusText))
return Error(response.statusText);}
);
}
The front end module waits for a button click and stores the text box in the name variable.
{
import {placeOrder} from 'backend/orderplaced.jsw';
export function button1_click(event, $w) {
placeOrder(
$w("#input1").value)
.then(function() {
console.log("Form submitted to backend.");
}
);
}
}
Output:
2
The code appears to be reaching the back end. I believe the problem is in my placeOrder function as I am not very familiar with JavaScript.
Your code seems legit. The problem is with the server. When I tried to send a POST request to that address I got a 500 Internal Server Error.
You may check this curl and test the service yourself:
curl -i -X POST -H "Content-Type:application/json" https://reliableeparts.pythonanywhere.com/user -d '{"name":"test123"}'
You are probably missing the correct object structure the server is expecting or missing proper headers to POST the server (or both...)
Make sure you're following the API this server allows
Related
I've got this cURL request working perfectly on remote interface just as it should
curl -XGET "https://server.host:8080/peregrine" -d '{"exchanges":["kucoin", "kraken"],"volume":10}' -k
I'm trying to build a little frontend app with Vue.js and need the above converted to an Axios get request.
I've been trying the following so far:
axios({
method: 'get',
url: 'https://server.host/peregrine',
data: {"exchanges":["kucoin", "kraken"],"volume":10}
});
putting params instead of data makes it a URL and remote server says that it received no data.
What am I doing wrong? Thanks.
Likely the problem could be that using GET you cannot pass data like you are doing. You have to pass them as query parameter.
Try to change your call with:
axios.get('https://server.host/peregrine', {
params: {"exchanges":["kucoin", "kraken"],"volume":10}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});
GET requests should not have request bodies.
CURL will allow you to make a GET request with one, but XMLHttpRequest and fetch (the HTTP APIs in browsers which axios wraps) will not.
Make a POST request instead. You might need to change the server-side code to support this.
Thanks for your replies!
Indeed there's no way to send data body with axios.get()
We ended up tuning the server side to accept normal generic GET requests. Thanks again to everyone who answered!
My goal is to fetch the status data from a UBNT radio (https://www.ubnt.com/) using an HTTP request. The web interface url is formatted as http://192.168.0.120/status.cgi. Making the request requires a authentication cookie. Using the cookie copied from the existing web interface I am able to successfully retrieve the data.
This is my current code using the Meteor framework.
radioHost = "http://192.168.0.120";
HTTP.call("POST", radioHost + "/login.cgi",
{
headers: {
"Content-Type": "multipart/form-data"
},
data: {
username: "ubnt",
password: "ubnt"
}
}, (err, res) = > {
if(err) return console.log(err);
var cookie = res.headers["set-cookie"][0];
HTTP.call("GET", radioHost + "/status.cgi", {
headers: {
cookie
}
}, (err, res) = > {
if(err) return console.log("Error");
console.log(res);
})
})
The above code achieves both request successfully. However the server is responding to the first with a faulty token ("set-cookie" string). Using the cookie from the existing web framework the response is correct.
Here is a library written in Python that I believe does a similar thing. https://github.com/zmousm/ubnt-nagios-plugins
I believe my problem lies within the HTTP request and the web api not cooperating with the username and password.
Thanks in advance for any help.
A direct POST request to a url is not a recommended way. When you open a browser you just don't directly login. You fetch the page and then submit/login
Not simulating this behavior may impact certain sites depending on how the server works.
So if always want to look at the simulating like a real user/browser would do, make a GET request first and then the POST.
Also capture any cookies from the first GET request and then pass the same on to the next one
There's a webapp that makes a request (let's call it /api/item). This request returns a json body with a field called itemData which is normally hidden from the user, but I want to make that shown.
So how do I make a userscript that listens for the request at /api/item and displays the itemData field?
For reference the way the webapp is making the request is:
return Promise.resolve(new Request(e,r)).then(sendCookies).then(addLangParam).then(addCacheParam).then(addXsrfKey).then(checkZeroRating).then(function(e) {
return fetch(e)
}).then(checkStatus).then(checkApiVersionMismatch).then(checkApiResponse)
Most of that is irrelevant, but the important part is Request (I think).
This webapp is not using XMLHttpRequest, but the Fetch API.
You can use the fetch-intercept npm module to intercept fetch requests. Example code:
import fetchIntercept from 'fetch-intercept'
fetchIntercept.register({
response(response) {
console.log(response)
return response
}
})
Do you have access to the promise returned ?
If so, then you may add another "then".
Otherwise, you may overwrite "checkApiResponse"
I am working on an app that will submit data to a REST API and have some questions.
How does jQuery know if my post request was successful or not? Is it only looking at the HTTP status?
Is there a convention on what to return from a POST request to a REST API?
JavaScript
$.post( '/API/removeUser', { Eid: id }, function(data) { row.remove(); } );
PHP SLIM Framework
$app->POST('/API/removeUser', function () use ($app) {
// Get the ID from the jQuery post
$Eid = trim(stripslashes(htmlspecialchars($_POST['Eid'])));
echo json_encode(removeFunction($Eid));
});
Your backend should always return the appropriate HTTP status code along with the actual data. 404 for resources that were not found, 403 for unauthorized requests, 200 for successful requests etc. Most AJAX libraries (including jQuery) will rely on those for determining the result of the operation.
If you need more fine-grained error reporting, you could always include a field like "errorCode" in your response that contains an application-level error code that you define yourself and react to accordingly in your frontend code.
I'm trying to use Parse Cloud Code to run a python script. I'm passing a parameter, but I seem to be getting an error. I'm not 100% sure what the problem is, but it seems like I'm not composing the url correctly. Any help would be appreciated.
My python code looks like this:
# a function that makes a sentence more exciting
def excited(sentence):
return sentence + '!!!'
Here's my code in main.js:
Parse.Cloud.define('testFunction', function(request, response) {
var someParam = request.params['testString'];
var url = 'http://mywebsite.com/test.py/excited&sentence=' + someParam;
Parse.Cloud.httpRequest({
url: url,
success: function(httpResponse) {
console.log(httpResponse.headers);
console.log(httpResponse.text);
response.success();
}, error: function(httpResponse, error) {
console.error('Request failed with response code ' + httpResponse.status);
}
});
});
EDITED:
Now I understand the problem better.
You are trying to call a python method from Parse.Cloud javascript based service. Based on their tutorials, I think you probably wanted the other way round.
Parse.Cloud allows you to deploy some server-side code in javascript. Then you can make REST API calls from your mobile app to the server endpoints by using either python or curl or any other language or tool. While testing, you can just call the end points from python on your box.
So your server code (in cloud/main.js) should look like this:
Parse.Cloud.define("testFunction", function(request, response) {
var excitedSentence = request.params.testString + "!!!";
response.success(excitedSentence);
});
This code creates a REST API endpoint at https://api.parse.com/1/functions/testFunction
Then you can call this API endpoint by using python (assuming you have Python installed on your box):
import json,httplib
connection = httplib.HTTPSConnection('api.parse.com', 443)
connection.connect()
connection.request('POST', '/1/functions/testFunction', json.dumps({
"testString": "This is an example sentence"
}), {
"X-Parse-Application-Id": "xxxxx_PUT_YOUR_ID_xxxxxxx",
"X-Parse-REST-API-Key": "xxxxxxxx_YOUR_KEY_xxxxxx",
"Content-Type": "application/json"
})
result = json.loads(connection.getresponse().read())
print result
If you don't have python installed, you can call the API endpoint by going to the online dashboard.
Go to: Your App -> Core tab -> API Console.
For endpoint, select post (this is important), and specify "functions/testFunction" in the text box.
In request body, specify: {"testString" : "This is an example sentence"}
Click "Send Request" and you should see the following output:
"result": "This is an example sentence!!!"