I am using ionic 2 Http.post method with php API. My problem is i am getting Disallowed Key Characters. error on client side. While i figured out in postman that this error arrives when i select form-data option from postman it says "Disallowed Key Characters." in response.
As well as when i select x-www-form-urlencoded option i get the response and my info updated successfully in mySQL server.
Here is my .ts file code:
let headers = new Headers();
headers.append('Access-Control-Allow-Origin:','*');
headers.append('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
let postData = {
FirstName:"testname",
LastName:"testlastname",
PhoneNumber:"12345",
EmailAddress:"test#gmail.com",
InsertedBy:"21"
};
this.http.post('http://localhost:889/api/user/users.json', JSON.stringify(postData),options)
.subscribe((data) => {
//var data = res.json();
console.log(data);
}
I think there is a problem while passing header. Somebody guide me where i am doing wrong?
Here is a screenshot of error:
This api works fine when selecting x-www-form-urlencoded with postman:
Related
I'm using axios to make HTTP request POST. Here's my axios code to request
async onFormSubmit(input_data){
const response = await axios.post('http://localhost:8080/auth/login', {
email: input_data['email'],
password: input_data['password']
});
After that in the backend I using codeigniter 4 and get the post request's value using this code
return json_encode($this->request->getPost('email'));
And then the data return is Null. How exactly to receive post data from axios post?
Nb:
I directly return the data just to look directly for the value that posted by axios
The value of input_data['email'] is not None (Already check that in console before do the axios post)
[SOLVED]
use getJson rather than getPost
I have a webservice (Actually generated with the drupal 7 plugin Service) accepting requests on 'http://mywebsite:8080/api_name/user' and checking possible connections against an 'api-key' variable in the requests, containing sort of a password.
Trying to connect to the service with my ionic2/cordova app result in a fail for the payload of the request results empty on the server side ($_REQUEST is an empty array and does not contain the api-key required, so that the request fails).
Debugging the request with https://requestb.in/ shows that the variable is in the body of the request, as expected.
The webservice is working well, on its side, for a post request sent by Google Postman go on successfully (thought I noticed a difference sending the postman request to requestb.in: 'api-key' parameter is not in the body, but in a part called "Form/Post Parameters" and the Content type is 'multipart/form-data' instead of application/json)
I am a bit confused about how my code (that seems correct) is not working...
Here is the code of the function trying to connect to the webservice:
register(username,password,email){
var headers = new Headers();
headers.append('Accept', 'application/json');
let options = new RequestOptions({ headers: headers });
let postParams = {
"api-key" : "someSecret",
"name" : "something",
"mail" : "somethingelse"
}
this.http.post("http://mywebsite:8080/api_name/user", postParams, options).subscribe(data => {
console.log("ok");
}, error => {
console.log("error:"+error);// Error getting the data
});
}
EDIT: i'm reading that "$_REQUEST is used to collect data after submitting an HTML form" so the problem lays actually in sending the request as a 'multipart/form-data' but how I can do that? Changing the 'Content-type' in the header seems not to be enough. I tried adding this (with no fortune)
headers.append('Content-type', 'multipart/form-data');
After hours of attempts, here it is the correct code:
register(username,password,email){
var headers = new Headers();
headers.append('enctype', 'multipart/form-data');
let options = new RequestOptions({ headers: headers });
let postParams:FormData = new FormData();
postParams.append("api-key", "something secret");
this.http.post("http://mywebsite:8080/api_name/user", postParams, options).subscribe(data => {
console.log("ok");
}, error => {
console.log("error:"+error); // Error getting the data
});
}
My webapp has Laravel as backend framework which provides a Restful API and in the fronend Angularjs is running.
I send different requests through the api and receive the responses and based on the code of response and data included, appropriate messages are shown to user.
Recently when I send requests using PUT method or POST method, when the data has problem in validation process and Laravel should respond with a 422 code in JSON format, instead I receive a text/html response with code 200. and then everything goes wrong.
This does not happen on my local machine, Only when I test the app in production environment this happens.
I also tested UnAuthorized response which is sent with 403 code, and it works flawlessly.
I tested both the automatic validation error for Laravel (as described in documentation: When using the validate method during an AJAX request, Laravel will not generate a redirect response. Instead, Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.) and also using the following method:
return response()->json(compact('errors'),422);
I should mention that I use following methods to send AJAX requests:
function save(data, url) {
return $http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/json'},
data: angular.toJson(data)
});
}
function update(data, url) {
return $http({
method: 'PUT',
url: url + data.id,
headers: {'Content-Type': 'application/json'},
data: angular.toJson(data)
});
}
needless to say I became totally confused!
UPDATE: It seems to be a problem with Laravel validation process. when the validation runs, request become erroneous. see the following piece of code:
public function altUpdate(Request $request){
$this->authorize('editCustomer', $this->store);
if (!$request->has('customer')){
return response()->json(["message"=>"Problem in received data"],422);
}
$id = $request->customer['id'];
$rules = [
'name' => 'required',
'mobile' => "required|digits:11|unique:customers,mobile,$id,id,store_id,$this->store_id",
'phone' => 'digits_between:8,11',
'email' => "email|max:255|unique:customers,email,$id,id,store_id,$this->store_id",
];
//return response()->json(["problem in data"],422); //this one works properly if uncommented
$validator = Validator::make($request->customer,$rules);
if ($validator->fails()){
$errors = $validator->errors()->all();
Log::info($errors);
return response()->json(["problem in data"],422);//this one is received in client side as a text/html response with code 200
}
$customer = Customer::find($id);
$customer->update(wrapInputs($request->all()));
if ($request->tags) {
$this->syncTags($request->tags, $customer);
}
$message = "Customer updated successfully!";
return response()->json(compact('message'));
}
I still don't know what's the problem of validation process. this code is working on my local machine without any problems but on the production server problem occurs.
I finally got that.
I had added a language file and the file was encoded in UTF-8-BOM, when I converted that file to UTF-8 without BOM things become correct.
the file was resources/lang/[the language]/validation.php and because of the encoding problem the headers were being sent while processing this file.
This question also helped me to find the problem:
Laravel redirect::route is showing a message between page loads
I setup fresh laravel 5.2 project and in my routes.php file I have:
Route::get('/happy', function () {
abort(403,'Unauthorized - its OK :)');
});
Route::post('/sad', function () {
abort(403,'Unauthorized - its not OK :(');
});
Here are screenshots from postman:
For GET i have good response status code = 403, but for POST i get bad response status code = 200. How to make POST status codes right(=403)?
I use body-raw POST mehtod for sending json (not in this exaplme).
Instead of using raw, use form data to send post value, then you will get an exact result
May be just do what is writen on Postman response: set 'always_populate__raw_post_data' to -1 in php.ini
I am trying to send a PUT request method from my Android app to my PHP endpoint but in my endpoint the PUT request is not recognized as a PUT request so I return Request method is wrong! message from my endpoint.
Android interface and request execution
Interface for activation
#PUT("device/activate.php")
Call<DeviceRegistry> registryDevice();
Executing the request
DeviceRegistryAPI registryAPI =
RetrofitController.getRetrofit().create(DeviceRegistryAPI.class);
Call<DeviceRegistry> registryCallback = registryAPI.registryDevice();
response = registryCallback.execute();
With this I am expecting a response but I am getting my endpoint error message.
My PHP endpoint
if($_SERVER['REQUEST_METHOD'] == "PUT"){
//doing something with the data
} else {
$data = array("result" => 0, "message" => "Request method is wrong!");
}
I don't know why the $_SERVER['REQUEST_METHOD'] == "PUT" is false but I wonder if I am missing something on Retrofit 2.
More Info.
I am using Retrofit2.
Update 1: Sending json into the body
I am trying to send a json using the body.
It is my json:
{
"number": 1,
"infoList": [
{
"id": 1,
"info": "something"
},
{
"id": 2,
"info": "something"
}
]
}
There are my classes:
class DataInfo{
public int number;
public List<Info> infoList;
public DataInfo(int number, List<Info> list){
this.number = number;
this.infoList = list;
}
}
class Info{
public int id;
public String info;
}
I changed the PUT interface to this:
#PUT("device/activate.php")
Call<DeviceRegistry> registryDevice(#Body DataInfo info);
But I am getting the same problem.
Update 2: Do I need Header
I have this header in my REstfull client:
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Do I need to put this on my request configuration? How do I do that if I need it?
Update 3: checking the request type of my sending post.
Now I am checking the type of the request. Because I am having the same problem with the PUT/POST requests. So If can solved the problem with the put maybe all the problems will be solved.
When I execute the request and asking and inspect the request it is sending the the type (PUT/POST) but in the server php only detect or GET?? (the below example is using POST and the behavior is the same)
Call<UpdateResponse> requestCall = client.updateMedia(downloadItemList);
Log.i("CCC", requestCall .request().toString());
And the output is a POST:
Request{method=POST, url=http://myserver/api/v1/media/updateMedia.php, tag=null}
so I am sending a POST (no matter if I send a PUT) request to the sever but why in the server I am receiving a GET. I am locked!!! I don't know where is the problem.
Update 4: godaddy hosting.
I have my php server hosting on godaddy. Is there any problem with that? I create a local host and everything works pretty good but the same code is not working on godaddy. I did some research but I didn't find any good answer to this problem so Is possible that godaddy hosting is the problem?
PHP doesn't recognize anything other than GET and POST. the server should throw at you some kind of error like empty request.
To access PUT and other requests use
$putfp = fopen('php://input', 'r'); //will be a JSON string (provided everything got sent)
$putdata = '';
while($data = fread($putfp, filesize('php://input')))
$putdata .= $data;
fclose($putfp);
//php-like variable, if you want
$_PUT = json_decode($putdata);
did not tested, but should work.
I guess the problem is that you don't pass any data along with PUT request, that's why PHP recognizes the request as a GET. So I think you just need to try to pass some data using #FormUrlEncoded, #Multipart or probably #Body annotations
To add header in your retrofit2 you should create an interceptor:
Interceptor interceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException
{
okhttp3.Request.Builder ongoing = chain.request().newBuilder();
ongoing.addHeader("Content-Type", "application/x-www-form-urlencoded");
ongoing.addHeader("Accept", "application/json");
return chain.proceed(ongoing.build());
}
};
and add it to your client builder:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(interceptor);
PHP recognises 'PUT' calls. Extracted from PHP.net:
'REQUEST_METHOD' Which request method was used to access the page;
i.e. 'GET', 'HEAD', 'POST', 'PUT'.
You don't need to send any header if your server isn't expecting any
header.
Prior to use Retrofit or any other networking library, you should check the endpoint using a request http builder, like Postman or Advanced Rest Client. To debug the request/response when running your app or unit tests use a proxy like Charles, it will help you a lot to watch how your request/response really looks.