I am using Alamofire in iOS 9 and am noticing that Alamofire is not sending the parameters to my PHP script in a POST method.
This is the PHP script:
if($_SERVER['REQUEST_METHOD'] != 'POST') {
echo '{"status": "error", "message" : "Only POST supported. You sent: '.$_SERVER['REQUEST_METHOD'].'"}';
return;
}
if (!isset($_POST['GENDER']) || !isset( $_POST['CHAR_COUNT_LOWER'] ) || !isset( $_POST['CHAR_COUNT_UPPER'] )) {
echo '{"status": "error", "message" : "Minimum parameters not set."}';
return;
}
Then, when firing my Alamofire POST request, I get the message:
swift:55 fetchData(_:completionHandler:): Only
POST supported. You sent: GET
And, finally, this is my Alamofire request:
Alamofire.request(.POST, url, parameters: ["CHAR_COUNT_LOWER":String(lowerValue), "CHAR_COUNT_UPPER":String(upperValue), "GENDER": String(gender!)] )
.validate()
.responseJSON { response in
QL1(response.description)
switch response.result {
case .Success:
var result = [BabyNames]()
let json = JSON(data: response.data!)
if json["status"] == "error" {
QL4(json["message"])
completionHandler(babyNames: [], error: StoreError.CannotFetch("Could not retrieve baby names"))
return
}
.......
I also tried changing the encoding to everything else but JSON, as my service does not take JSON as input.
It's a simple service that reads $_POST["param"]
Anything I am doing wrong?
Thanks.
EDIT:
Still going crazy about it. Installed Charles to check what was the request coming out of my PC and here it goes:
EDIT 2:
Change the Alamofire request encoding to JSON:
Alamofire.request(.POST, url, parameters: parameters!, encoding: ParameterEncoding.JSON )
Now I can see a GET and a POST request. The Post request:
URL http://example.com/backend/names/query_names.php
Status Complete Response Code 301 Moved Permanently
Finally found what the problem was.
My request URL was set to http://server.com/api
When I changed it to http://www.server.com/api
That got it working. I don't know honestly why that would happen and if that's something to do with the .httpaccess but that's it.
Related
I want to post a message to slack on x channel
I need to send the following x parameters
how do I send the following parameters to a website
"channel": "XXXXX",
"token": "token",
"text": "text"
Add your parameters to the end of Slack's chat.postMessage endpoint like this:
http://slack.com/api/chat.postMessage?token=XXX&channel=XXX&text=XXX
Then make a GET request to that URL to post your message. Personally I'd suggest doing this as a Node application and using the request package obtained via npm. Makes it very easy.
Post message to Slack in a Node App
Create a new node project and then change to that folder on the command line
On the command line type npm install -g request to install the request module for your project
Inside the index.js file (or wherever you plan on calling the API) do as follows:
//Import request module
var request = require('request');
//Replace your token, channelID and text here
var path_to_call = 'http://slack.com/api/chat.postMessage?token=XXX&channel=XXX&text=XXX';
request(path_to_call, function(error, response, body) {
if (!error && response.statusCode == 200) {
console.log('Success');
} else {
console.log(error);
}
});
If you just want to post messages I would recommend to use an Incoming Webhook. They are specifically designed for that purpose and easier to use than API calls.
An Incoming webhook is a custom URL that you can create for your Slack team and then use to send messages into any channel. For sending a message you only need to submit your message in JSON format along with some parameters as POST request to your webhook URL.
If you are using PHP scripting on your website then you best use CURL for the call.
Check out the documentation for details on how to use it.
var url = "https://slack.com/api/chat.postMessage";
var auth_token = auth_token; //Your Bot's auth token
var headers = {
"Authorization": "Bearer " + auth_token,
"Content-Type" : "application/json"
}
var body = {
channel: userSlackId, // Slack user or channel, where you want to send the message
text: "Your text goes here."
}
request.post({
"url": url,
"headers": headers,
"body": JSON.stringify(body)
}, (err, response, body) => {
if (err) {
reject(err);
}
console.log("response: ", JSON.stringify(response));
console.log("body: ",body);
});
You have to set headers as Authorization, and add Bearer before your token as it is mentioned in slack docs. Also, send user/channel in body. Here I'm providing the link for the same for your reference https://api.slack.com/methods/chat.postMessage#channels . Hope this helps.
Not sure which language you're using, but if using Postman to test, you can try the following format.
raw Postman request
POST /api/chat.postMessage HTTP/1.1
Host: slack.com
Content-Type: application/json
Cache-Control: no-cache
{
"text": "This is a line of text.\nAnd this is another one.",
"token": "XXXX",
"channel": "XXXX",
}
I have an interceptor for authentication.
I want to get a header out of the response when I get a 401 response error.
Interceptor is:
function ($httpProvider, fileUploadProvider) {
$httpProvider.interceptors.push(function($q, $localStorage) {
return {
'request': function(config) {
if ($localStorage.token) {
config.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return config;
},
'responseError': function(response) {
if (response.status === 401) {
//$rootScope.$broadcast('unauthorized');
// WWW-Authenticate: Bearer error="invalid_token"
var authResult = response.headers('WWW-Authenticate');
if (authResult.indexOf("invalid_token")>-1) {
$localStorage.token = null;
$timeout(function(){
;
});
}
}
return response;
}
};
I want to get the WWW-Authenticate header from the response.
I can confirm the header is in the response of the web service call by looking at the network tab in Chrome developers tools. If I set a break point in the response handler function and then run console.log(response.headers()) in the console I get:
Object {}
undefined
How do I get to the response headers?
The responseError function receives rejection instead of response.
Therefore if you want to access response headers, what you need is like below.
'responseError': function(rejection) {
if (rejection.status === 401) {
console.log(rejection.config.headers);
}
}
I hope this would help you. :)
Although I know this is not answer and should post as comment, I post it here to use screen capture image.
I tried to get a response header with my test enviroment like below.
nodejs server
res.setHeader('WWW-Authenticate', 'invalid_token');
res.status(401).send();
angularjs
'responseError': function(rejection) {
if (rejection.status === 401) {
console.log(rejection.headers('WWW-Authenticate'));
}
}
Chrome dev tool screen capture
As you can see, I could get the response header correctly.
Therefore I think that there seems to be some problem in your server code where you set a response header.
Would you like to show us your chrome dev tool screen capture and your server code where you set the response header?
I am able to successfully POST from AngularJS to my Sinatra route such that I get a "200" Status.
When I inspect in Chrome, I see the request payload as follows:
{"input":"testing"}
But response is empty.
Here is how I am POST-ing:
$http({
method: "POST",
url: "http://floating-beyond-3787.herokuapp.com/angular",
/*url: "https://worker-aws-us-east-1.iron.io/2/projects/542c8609827e3f0005000123/tasks/webhook?code_name=botweb&oauth=LOo5Nc0x0e2GJ838_nbKoheXqM0",*/
data: {input: $scope.newChat}
})
.success(function (data)
{
// $scope.chats.push(data);
$scope.chats.push($scope.newChat)
// if successful then get the value from the cache?
})
.error(function (data)
{
$scope.errors.push(data);
});
};
$scope.newChat = null
Chrome under Request Payload shows it properly -- as above.
When I check the logs in Heroku where I run my Sinatra app, I can't tell if I am properly processing the request payload. And I'm definitely not getting anything in the Response:
post '/angular' do
puts "params: #{params}"
puts params[:input]
puts #json = JSON.parse(request.body.read)
return RestClient.post 'https://worker.io' {:send => params[:input]}
end
My expectation is:
The Sinatra app can receive the payload :input
It can successfully post to my worker on iron.io
It can return something back in the Response to Angular JS along with Success.
Is this possible and if so, how?
Possibly you are running into a case where the request.body has already been read further up the chain before hitting your route.
Try the following
request.body.rewind
request_payload = JSON.parse request.body.read
This is a fairly common issue encountered in Sinatra so if this addresses your issue you may want to put it in a before filter.
before do
request.body.rewind
#request_payload = JSON.parse request.body.read
end
Also the following will not work with a JSON payload.
params[:input]
The params[:field] style works if the Content-Type is application/x-www-form-urlencoded to allow accessing form data in a traditional web application style. It also works to pull params off a parameterized route; something like the following.
post '/angular/:data'
puts params[:data]
# Do whatever processing you need in here
# assume you created a no_errors var to track problems with the
# post
if no_errors
body(json({key: val, key2: val2, keyetc: valetc}))
status 200
else
body(({oh_snap: "An error has occurred!"}).to_json) # json(hash) or hash.to_json should both work here.
status 400 # Replace with your appropriate 4XX error here...
end
end
Something I did recently was to use this last style post 'myroute/:myparam and then Base64 encode a JSON payload on the client side and send it in the URL :myparam slot. This is a bit of a hack and is not something I would recommend as a general practice. I had a client application that could not properly encode the JSON data + headers into the request body; so this was a viable workaround.
I have a login system that will hold the session for 2 hours. After 2 hours, when the client makes API calls, they get back an error:
{
"Success": false,
"Error": {
"ErrorCode": "002",
"ErrorMessage": "Session expired"
}
}
I need to then redirect the client to /login when that happens. The problem is that I get that error from individual API calls, so rather than change EVERY API call, is it possible to have a global interceptor?
Following the example for Interceptors found here, you can do something like the following in the response section of the interceptor:
response: function(resp){
// resp.data will contain your response object from the server
if(resp.data && !resp.data.Success){
// check for error code
if(resp.data.Error && resp.data.ErrorCode === '002'){
$location.path('/login');
return $q.reject(resp);
}
}
return resp || $q.when(resp);
},
This is assuming that your server is returning a 200 when you get this error message, not on a 401 or 403, but that's what it looks like you're doing. Hope that helps.
I am writing a google-chrome extension, that needs to make ajax requests to a server, send some data, and receive some data back. My server is Tomcat 6.0, running on localhost.
I am able to receive all the data on the server side, do all the processing I need, and send a response back to the extension,
but the status i get in the callback is 0, and responseText="".
my guess is that the problem lies either in the server - returning a response to a request originating from chrome-extension://... url, or in the extension - receiving a response from localhost:8080.
I've set the necessary permissions of course, and I tried setting content-type of the response to "text/xml", "text/html" and "text/plain" - it makes no difference.
I've tried using ajax both with XMLHttpRequest and JQuery - same problem with both.
I've found these issues, but they don't seem to solve my problem:
1. http://www.plee.me/blog/2009/08/ajax-with-chrome-empty-responsetext/
2. http://bugs.jquery.com/ticket/7653
here's my code:
bg.js (background page)
function saveText(data) {
var requrl = serverUrl + addTextUrl;
var params = json2urlParams(data);
jQuery.ajax({
type : "POST",
url : requrl,
data : params,
success : function (data, textStatus, XMLHttpRequest) {
console.log("Data Saved: " + msg);
}
});
// var xhr = new XMLHttpRequest();
// xhr.open("POST", requrl, true);
// xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// xhr.onreadystatechange = function (progress) {
// if (xhr.readyState == 4) {
// console.log("Data Saved: " + this.response);
// }
// };
// xhr.send(params);
}
addContentServlet.java: (server side)
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
ErrorCodes error = addContent(request, response);
response.setContentType("text/plain");
//response.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
//response.setIntHeader("errorCode", error.ordinal());
response.getWriter().write(error.toString());
response.setIntHeader("errorcode", error.ordinal());
if(error == ErrorCodes.SUCCESS){
response.setStatus(error.toHttpErrorCode());
response.flushBuffer();
}
else{
response.sendError(error.toHttpErrorCode(), error.toString());
}
}
EDIT:
I've noticed in the chrome console of the background page that for every ajax that returns to the extension i get a
XMLHttpRequest cannot load
http:// localhost:8080/stp_poc/MyServlet.
Origin
chrome-extension://fmmolofppekcdickmdcjflhkbmpdomba
is not allowed by
Access-Control-Allow-Origin.
I tried loosing bg.js and puting all the code in the main page instead - to no avail.
how come XMLHttpRequest agrees to send the request, but not receive it back??
Maybe a server-configuration problem? I'm a newb, so maybe i missed something basic, like a header in the response
EDIT
I've finally pinned the problem:
I shouldn't have included the port number in my permission. Here's the wrong permission I wrote:
"permissions" : [
"http://localhost:8080/"
]
And here's the correct form:
"permissions" : [
"http://localhost/"
]
everything seems to works fine now.
The problem was that I shouldn't have included the port number in my permission.
Here's the wrong permission I wrote:
"permissions" : [
"http://localhost:8080/"
]
And here's the correct form:
"permissions" : [
"http://localhost/"
]