I have seen a lot of questions here with the exact same problem, but none of them have a solution that works for me.
I have a NodeJS server setup and in an Angular controller I'm trying to get a contact form working. On form submission I call this function (this is only one of the many variations on a POST request I've tried):
$scope.submit_contact_form = function(){
$http({
method: "post",
url: 'http://' + window.location.host + "/form-u10657.php",
data: $scope.form_data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data) {
$scope.status_message_toggle("Success");
}).error(function(){
$scope.status_message_toggle("Problem sending mail", 'warning');
});
};
But it always returns a 404 not found error. The php file is definitely in the right directory. Going to the url with a GET request works.
What is different in my setup, that I haven't seen in other questions, is that I am using a NodeJS server and ngRouteProvider.
Other answers have said to allow NodeJS to accept POST requests, but it hasn't been necessary to configure NodeJS before, and I would like to avoid it now.
Is there a way to fix it just in Angular? And if not what should I do with NodeJS to get it working?
Related
I am currently learning the Laravel API, and have been developed a very simple API that retrieves data from the database by simply entering 127.0.0.1:8000/api/XXX to the browser, however, when I tried to use ajax call to get data from the exact same url, the ajax always showed that the HTTP request was failed, the ajax codes I used are following:
$.ajax({
url: "127.0.0.1:8000/api/XXX",
success: function(data) {
let response = JSON.parse(data);
displayResult(response, 1);
}
})
.done(function() {
alert( "success" );
})
.fail(function() {
alert( "error" );
})
And this code always resulted in alert("error");, therefore I am wondering that maybe there are some Routes needed to be written in order to let the API properly processes HTTP request? I have already defined a route in routes\api.php:
Route::apiResource('XXX', 'XXXController');
PS: when entering the API URL to the browser, it worked fine, it went wrong when doing an ajax call with the API URL.
Edit
These are the errors I got from the browser console after I used function(jqXHR, textStatus, errorThrown) to catch the errors
DOMException: Failed to execute 'open' on 'XMLHttpRequest': Invalid URL
at Object.send (https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js:2:79420)
at Function.ajax (https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js:2:77118)
at retrieveAllBooks (http://127.0.0.1:8000/js/api-query.js:25:5)
at HTMLInputElement.<anonymous> (http://127.0.0.1:8000/js/api-query.js:10:7)
at HTMLInputElement.dispatch (https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js:2:41772)
at HTMLInputElement.y.handle (https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js:2:39791)
I am not exactly sure why it is an invalid URL, since if I copy and paste this link to browser, nothing goes wrong...
(Posted on behalf of the question author).
Actually the solution is simple, just add http:// to the url.
We are trying to call from index.html on local, a simple PHP file hosted on webhost000 to receive a response. PHP file is:
<?php
if (isset($_POST['name'])) {
$name = $_POST['name'];
echo ($name);
}
?>
We would like to simply input a character on a textbox in html.index and receive the same character as response from the php. We are using an ajax call to do this in html file:
<script>
$(document).ready(function() {
$('#name').keyup(function() {
var name = $('#name').val();
var request = $.ajax({
url: "https://nedo93.000webhostapp.com/phpdemo.php",
method: "POST",
data: { name : name },
dataType: "html"
});
request.done(function( msg ) {
alert( "Request done: " + msg );
});
request.fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
});
});
</script>
(The remaining html should not be important, it works perfectly, tested and retested)
If we try to debug this we can see that the file is found, the request is sent, but we can't receive a response: screenshot
If we use this browser function instead, we can send data and receive a response without a problem, don't know if this can help.
Thank you in advance if you can answer this question.
This is because your PHP script is hosted on a different server and your AJAX call code is on local.
For AJAX to run, there is same-origin policy. Under this policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin (means both are on same domain). Read more about same origin policy here.
The same-origin policy prevents some Ajax techniques from being used across domains, although the W3C has a draft of the XMLHttpRequest object that would enable this functionality. Methods exist to sidestep this security feature by using a special Cross Domain Communications channel embedded as an iframe within a page, or by the use of JSONP, websockets, cross-domain messaging or cross-domain resource sharing.
So in short you will not be able to access the PHP request residing on a 000webhost server to be accessed using AJAX code on local.
Either you host the AJAX code on the same 000webhost domain as well or enable cross-domain resource sharing on 000webhost domain where your PHP code is running.
As far I know, 000webhost is a free server and doesn't supports these changes. So you will have to either get a better server or test this all in a local.
Also as you mentioned in your query, all HTTP requests like GET, POST, PUT works cross domain. But for AJAX, no its not so straight forward.
Hope this helps!
use json_encode
your code should be....
<?php
if (isset($_POST['name'])) {
$name = $_POST['name'];
header('Content-Type: application/json'); //just used as info for your application
echo json_encode($name); //encode to JSON object
}
?>
after that do JQuery validation for checking Json reply (specially for error).
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 am not any kind of RESTful API expert, but I have a simple PUT/DELETE function in an AngularJS app that has been functioning as expected until now. I am trying to work out whether this problem is likely to lie in my app, or in the (php) back-end that is running the endpoint. Other REST services are functioning normally & the server appears to be running fine.
This function only ever calls PUT or DELETE, assigned as var method:
if (food.favourite === true) {
method = "PUT";
console.log("method is " + method)
} else if (food.favourite === false) {
method = "DELETE";
console.log("method is " + method)
}
$http({
method: method,
url: $scope.URL
}).success(function (data, status, headers, config) {
console.log(method + " successful")
}).error(function (data, status, headers, config) {
console.log(method + " not successful")
});
I have one $http GET in my app that uses a different endpoint. There is no $http GET pointing to this endpoint anywhere in my app- I have searched extensively.
When I trigger the function containing the $http above, the console shows:
method is PUT
GET http://localhost:8888/api/ext/51/ 500 (Internal Server Error)
PUT not successful
Why would I be receiving a GET error on an unsuccessful PUT request? Does this point to a problem in my function, or a problem with the endpoint?
Thank you for any help in understanding this problem.
Update 1
Info from the Network panel: calling the $http function above triggers two simultaneous requests, one 'PUT' and one 'GET'. The 'PUT' returns a 301 code, and the 'GET' returns a 500 server error (which I think is to be expected, as this endpoint is not set up to respond to 'GET', only to 'PUT' and 'DELETE').
So: why would my code be generating two simultaneous requests with different methods?
For future seekers of answers to similar questions: it is a standard behaviour (of REST in general or this implentation? Not sure) to try to return a GET for every action that is called. Evidence for this is that if I check the Network panel for all the other (successful) $http functions, they also have two actions visible: the original PUT/GET/DELETE etc, + a GET.
We are seeing a 500 Error on the GET for these particular requests because the configuration of this particular endpoint does not allow for a GET. This should not have any effect on the PUT/DELETE actions on this endpoint- the 500 Error is not related to the reason why the PUT/DELETE actions weren't working. In terms of trying to solve this specific problem, it's a red herring.
The reason the PUT/DELETE was not working was because the service was broken on the server-side.
I ran into this and the issue was in how I was outputting the errors in the first argument for header. They need to be in this format:
header('400: Error', true, 400);
or in your case, of course:
header('301: Moved Permanently', true, 301);
header('Location: ' . $url);
Note that this WILL NOT work:
header('Some Random Text', true, 400); // $http.error shows status of 500
I'm trying to create a Javascript client API service which calls the API of my site. This will be cross domain and i'm aware of the problems this causes. However, I need the user to send through some user credentials (whether that be their username and password encoded obviously or an API key + secret) so that I can return user specific details.
I initially looked at using the jsonp datatype however this doesnt allow you to set any custom headers so ruled this out.
I've been searching the web for a while and been unable to find a secure way of doing this cross domain, has anyone had any success with this and can give me some advice?
UPDATE:
I've tried this following code as suggested by lu1s, however I get an alert of 'boo' as stated n the error function..
$.ajax({
url: 'http://www.dotsandboxes.co.cc/__tests/cors.php',
type: 'GET',
dataType: 'json',
success: function() { alert('hello!'); },
error: function() { alert('boo!'); },
beforeSend: function (xhr) {
xhr.setRequestHeader('securityCode', 'Foo');
xhr.setRequestHeader('passkey', 'Bar');
}
});
Thanks
You can. Try adding the Allow-Access-Control-Origin: * to your HTTP response headers, as well as the correct content-type.
Try with a simple PHP script like this:
<?php
header('Access-Control-Allow-Origin: *');
header('Content-type: text/json');
echo json_encode(array('success'=>true,'data'=>'foobar'));
?>
Check this site to read more info about cross-origin: http://enable-cors.org/
About the authentication, it's NOT recommended to send usernames or passwords, even if they're encrypted. As you stated, it's better to pass a token in the URL. Best if following standards like http://oauth.net/2/ .