I am working on Angular4 Project.
For testing, first I had done the get request to any json api and its worked well.
Now I am working to connect the php file and testing it. In test.php I had
echo "string";
Now in console I am getting this error:
XMLHttpRequest cannot load http://localhost/php-file/test/test.php.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:4200' is therefore not allowed
access.
I also attached screenshot of it. I had googled it but unable to get any solution for this.
then I had edited the test.php like below. Is it right way to do so?
<?php
header("Access-Control-Allow-Origin: *");
$data = ['news','dfdf','ddd'];
echo json_encode($data);
?>
This is how you need to do. You need to include headers in angular as well.
import { Http, Headers, Response, RequestOptions } from '#angular/http';
headers = new Headers();
requestOptions = new RequestOptions();
this.headers.append('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
this.headers.append('Cotent-Type', 'application/json');
this.requestOptions.headers = this.headers;
return this.http.post("http://localhost/php-file/test/test.php", this.requestOptions).map(res => res.json());
This is how you should make post request. Make sure to subscribe this call and then you can get data from return.
I hope it helps.
Related
I am trying to post data to server. My php side is working fine. When I tried using postman post is working. But from angular I am getting 405 (Method Not Allowed) error:
zone.js:2935 OPTIONS http://angularslim.local/public_html/users 405 (Method Not Allowed)
Failed to load http://angularslim.local/public_html/users: Response for preflight has invalid HTTP status code 405.
My codes are below:
Inside my service I have following code.
#Injectable()
export class AuthService {
constructor(private http: Http) {}
register(user:User){
this.http.post("http://angularslim.local/public_html/users", user).subscribe((res: Response) => {
console.log("inside");
})
}
And in my php section I do have these lines
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
Did you try passing the form value by JSON.stringify(user). I had a same issue before. Later I found that my problem was that.
this.http.post("your api url", JSON.stringify(user))
.subscribe(
(val) => {
console.log("POST call successful value returned in body", val);
});
Hope this works for you.
You need to allow cross origins AND methods
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Also try this https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
In addition, i suggest you to use HttpClient (http is deprecated) and HttpResponse
If you use Slim, this is mostly because your Javascript code sends HTTP OPTIONS request while there is no route that handle HTTP OPTIONS.
You need to add a route that handle OPTIONS request or modify any Javascript code that cause preflight request to be sent (by making it a simple request. Take a look at this question Why is an OPTIONS request sent and can I disable it?).
To add route that handle OPTIONS
$app->options('/users', function ($request, $response, $args) {
//do something here
]);
More information:
Slim Router documentation
Why is an OPTIONS request sent and can I disable it?
I've got a very strange issue.
local hosted PHP Slim App using XAMPP (localhost:4040)
local hosted Angular 4 App using CLI (localhost:4200)
Making API Requests using "Postman" and browser is no problem, everything works fine.
Now I'm integrating the requests into my Angular app using import { Headers, Http } from '#angular/http'; and observables.
const requestUrl = 'http://localhost:4040/register';
const headers = new Headers({
'content-type': 'application/x-www-form-urlencoded'
});
this.http
.get(requestUrl, {headers: headers})
.map(response => response.json())
.subscribe(result => {
console.log(result);
}, error => {
console.log(error);
});
The request always fails with:
Failed to load http://localhost:4040/register: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
But: I am definitely sending these headers!
public static function createJsonResponseWithHeaders($response, $requestedData)
{
// Add origin header
$response = $response->withHeader('Access-Control-Allow-Origin', '*');
$response = $response->withHeader('Access-Control-Allow-Methods', 'GET');
// Add json response and gzip compression header to response and compress content
$response = $response->withHeader('Content-type', 'application/json; charset=utf-8');
$response = $response->withHeader('Content-Encoding', 'gzip');
$requestedData = json_encode($requestedData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
$response->getBody()->write(gzencode($requestedData), 9);
if (!$requestedData || (count($requestedData) === 0)) {
return $response->withStatus(404)->write('Requested data not found or empty! ErrorCode: 011017');
}
return $response;
}
What I already tried for solving:
Run Slim App inside a Docker Container to get a different origin than localhost - same behaviour
Add allow-origin-header right on top of the index.php
header('Access-Control-Allow-Origin: *'); - same behaviour
Your requests are blocked because of CORS not being set up properly. There are other questions that address this, e.g. How to make CORS enabled requests in Angular 2
What you should ideally look at using is a proxy that forwards your requests to the API, the latest Angular CLI comes with support for a dev proxy (see https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md) out of the box. You set it up with a proxy.conf.json that could look like this:
{
"/api": {
"target": "http://localhost:4040",
"secure": false,
"pathRewrite": {"^/api" : ""}
}
}
What this piece of code does is any requests from Angular to a URI matching /api will be forwarded to localhost:4040.
Note that you will also need to figure out how your app will talk to the API server in a non-dev environment. I have been happy with using Nginx to serve Angular files, and act as proxy for the API.
Sorry, my bad. The solution is simple:
The "Cache-control" header in the request seems to be not allowed, although it worked fine when testing the api with Postman.
I removed the header from the request and everything worked well.
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.
I'm new in REST API. I'm building up a test environment and trying to make a handshake between Rest API and Client side PHP.
My JSON data is at
http://localhost:50417/api/device
the data is like:
[
{"Truck_ID":1,"Company":"Food Mall","Distance":2000},
{"Truck_ID":2,"Company":"Food Mall","Distance":4000},
{"Truck_ID":3,"Company":"Food Mall","Distance":3050}
]
I'm trying to act like a client, use PHP to get the data, and put the data in an array. What I tried on client side which is http://localhost:8080 is
<?php
$url = "http://localhost:50417/api/device";
$response = file_get_contents($url);
echo $response;
?>
I also tried js like
<script type="text/javascript">
$(document).ready(function(){
$.getJSON("http://localhost:50417/api/device",
function(data){
alert (data) // this will show your actual json array
});
});
</script>
But no matter what I tried, I always get a "No 'Access-Control-Allow-Origin' header is present on the requested resource." What could be the problem? How clients generally get the data from server using REST API? Thank you.
allow cross origin requests
Enable it in the .htaccess by putting the below line
Header set Access-Control-Allow-Origin "*"
or try from php
<?php
header('Access-Control-Allow-Origin: *');
$url = "http://localhost:50417/api/device";
$response = file_get_contents($url);
echo $response;
?>
I am developing an UI for a REST repository using PHP and the PEAR HTTP REQUEST package (http://pear.php.net/package/HTTP_Request/).
I created a HTTP GET request and it delivers the requested rdf/xml file as expected. But I want to extend this request and I can't get this working.
The repository allows sending zip files which are attached to an id. So I have to call the same URL which delivers the rdf/xml data, but I have to change the HTTP GET header from xml to accept: application/zip, before executing my request. This should deliver the zip instead of the rdf/xml file.
$req =& new HTTP_Request();
$req->setMethod(HTTP_REQUEST_METHOD_GET);
$req->setURL($url);
$req->clearPostData();
if (!PEAR::isError($req->sendRequest())) {
$response2 = $req->getResponseBody();
} else {
$response2 = "";
}
echo $response2;
Does anyone know how to modify the GET call to get this done? I really need help!
Furthermore I want to create a HTTP PUT request which uses multipart/form-data. Does anyone know how to make this?
Please help me! Thanks!
For your first question, you can set the Accept field of your GET request header by:
$req->addHeader('Accept', 'application/zip');
# assuming that this will trigger the server to respond with the zip and not xml
Question number 2:
# Set method to PUT
$req->setMethod(HTTP_REQUEST_METHOD_PUT);
# Attach file to request
$req->addFile('file_upload_field', '/path/to/file.ext', 'application/zip');
Read up more on file uploads using HTTP_Request.
To modify the request headers, take a look at the addHeader() method of the HTTP_Request object: http://pear.php.net/manual/en/package.http.http-request.headers.php
To change the method, use the setMethod(): http://pear.php.net/package/HTTP_Request/docs/latest/HTTP_Request/HTTP_Request.html#methodsetMethod