I am trying to fetch some JSON data. I can access the data just fine in a regular web browser, like this: http://www.ebrent.net/apis/tsp.php?fund=G+Fund&start=2003-01-01&end=2004-01-01, but I cannot get it to work in jQuery. What am I doing wrong?
Please take a look at my jsFiddle: https://jsfiddle.net/MrSnrub/mq31hwuj/
var tsp_api = '//www.ebrent.net/apis/tsp.php?start=2003-01-01&end=2004-01-01';
$.getJSON( tsp_api, function(json) {
// This alert never gets called.
alert("Success!");
// Set the variables from the results array
var data = json;
// console.log('Data : ', data);
// Set the div's text
$('#div-data').text(data);
});
You cannot get the result because the remote site doesn't have CORS enabled:
If you look at the console, you'll see:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
http://www.ebrent.net/apis/tsp.php?start=2003-01-01&end=2004-01-01.
(Reason: CORS header 'Access-Control-Allow-Origin' missing).
You can bypass CORS by using something like anyorigin.com, i.e.:
$.getJSON('http://anyorigin.com/get/?url=http%3A//www.ebrent.net/apis/tsp.php%3Fstart%3D2003-01-01%26end%3D2004-01-01&callback=?', function(data){
$('#div-data').html(data.contents);
});
This works if you run the your server without using https. Note fetchApi was used instead of jquery Library as its not readily available in the browser
var tsp_api = 'https://www.ebrent.net/apis/tsp.php?start=2003-01-01&end=2004-01-01';
function fetchData(url) {
return fetch(url, {
method: 'get'
}).then(function(response) {
return response.json();
}).catch(function(err) {
console.log(error);
});
}
fetchData(tsp_api).then((data)=> console.log(data)).catch((err)=> console.log(err));
This won't work on jsfiddle using HTTPS, the browser will refuse to load any resources over HTTP. As you've tried, changing the API URL to have HTTPS instead of HTTP typically resolves this issue. However, your ebrent.net did not allow CoRS for HTTPS connections. Because of this, you won't be able to get your result for jsfiddle
Related
hi guys i'm getting stuck in my code i'm requesting to a php api to get data with using jquery ajax. please help me with a solution
Ajax code
$.ajax({
url: request_url+"courses.php",
type: 'POST',
dataType: 'jsonp',
cors: true ,
contentType:'application/json',
data: { request_courses: courses },
secure: true,
headers: {
'Access-Control-Allow-Origin': '*',
},
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa(""));
},
success: function (data){
console.log("helo "+data);
}
});
Php Api code
if(isset($_POST['request_courses'])){
$courses = mysqli_query($conn, "SELECT * FROM `courses`");
while ($rows = mysqli_fetch_assoc($courses)) {
$data[] = $rows;
}
echo json_encode(array('status' => 1,'message'=>'responce_courses','data'=>$data));
}
Error While runing this code
courses.html:1 A cookie associated with a cross-site resource at http://localhost/ was set
without the `SameSite` attribute. A future release of Chrome will only deliver cookies with
cross-site requests if they are set with `SameSite=None` and `Secure`. You can review
cookies in developer tools under Application>Storage>Cookies and see more details at
https://www.chromestatus.com/feature/5088147346030592 and
https://www.chromestatus.com/feature/5633521622188032.
Access to XMLHttpRequest at 'file:///home/punkaj/Music/Cordova/ithub/www/index.html' from
origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for
protocol schemes: http, data, chrome, chrome-extension, https.
jquery.js:2 GET file:///home/punkaj/Music/Cordova/ithub/www/index.html net::ERR_FAILED
send # jquery.js:2
ajax # jquery.js:2
h # plugins.js:45
i # plugins.js:45
dispatch # jquery.js:2
y.handle # jquery.js:2
First off, are you sure of the file URLs? 'file:///home/punkaj/Music/Cordova/ithub/www/index.html' seems a bit sketchy IMO. Make sure that it's correct.
And secondly, looks like the AJAX referenced file (courses.php) is trying to set a new cookie on the browser, which is a bad practice in REST APIs. It's better to just return/output whatever value you want, and when you have that value in your 'success' AJAX function, you can save it there as a cookie back in the original script.
Lastly, it looks like you're getting the file directly by using an FTP protocol (file:///) rather than an HTTP protocol (http://) to get the content of the HTML file. Can't provide any further assistance on that without seeing the source code
This scenario uses Access-Control-Allow-Credentials alongside the POST method to manage server-side PHP session variables that must remain intact.
For reference, the front-end is a create-react-app project running at http://localhost:3000 and the back-end is PHP running on example.com.
Achieving this with the $.ajax() method is easy and straightforward.
UseAjax(incomingData) {
return new Promise(function(resolve, reject) {
$.ajax({
url: 'http://example.com/api.php',
type: 'post',
data: incomingData,
xhrFields: { withCredentials: true },
success: function(data) {
console.log(data)
}
})
.then((data,status) => {
// Get the result and transform into valid JSON
if ( typeof data === typeof 'str' ) {
try {
data = JSON.parse(data);
} catch(e) {
reject(data,status);
console.log('Exception: ', e);
console.log('API Returned non-JSON result: ', data);
}
}
return data;
}).then((dataObject) => {
console.log('dataObject:');
console.log(dataObject);
resolve(dataObject);
});
});
}
Oddly enough though, when using the fetch() API, it is under the impression that I am not allowing CORS. Of course I have CORS enabled as this request works fine with Ajax and only fails while using the fetch() API.
Here is a look at what I tried while using the fetch() API.
UseFetch(requestData) {
return new Promise(function(resolve, reject) {
console.log('Relay() called with data: ', requestData);
fetch('http://example.com/api.php', {
method: 'POST', // or 'PUT'
body: JSON.stringify(requestData), // data can be `string` or {object}!
headers: new Headers({
'Content-Type': 'application/json'
})
}).then((result) => {
// Get the result
return result.json();
}).then((jsonResult) => {
// Do something with the result
if ( jsonResult.err )
reject(jsonResult);
console.log(jsonResult);
resolve(jsonResult);
});
});
}
It provides this error.
Failed to load http://example.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
On the PHP side, I am using a simple output to ensure nothing else is going wrong causing the error on the server's side.
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: http://example.com');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type, Authorization, x-requested-with');
echo json_encode(['data'=>'result']);
?>
I have followed many questions, but most notably this question with a very thorough explanation of the issue and possible solutions.
For now, I am just using the tried-and-true $.ajax() to complete this task, but I am wanting to fully understand the fetch() API to the extent necessary to replicate this functionality as it seems like something very basic from my experience.
In your PHP code, you've specified header('Access-Control-Allow-Origin: http://example.com');. This is wrong - you need to specify the value passed in the Origin request header (which in your case would be http://localhost:3000):
header('Access-Control-Allow-Origin: http://localhost:3000');
Ideally you wouldn't hardcode it - you'd just extract the Origin request header and pass that back.
BTW, I believe that JQuery's $.Ajax uses fetch() under the covers (just like XmlHTTPRequest()). Basically, everything uses fetch...
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).
I'm using a device detection PHP script on the server, mobiledetect.net and normally the user's browser would make a direct call to that on the server and so obviously the detection script would get all the HTTP headers (that it uses for device detection) directly that way.
If I call the same server side PHP detection script via a JQuery AJAX call from my javascript running on the user's browser, does it receive all the HTTP headers it needs for detection, as it would with the direct method? i.e. does JQuery allow or set all the HTTP headers for the AJAX call on the script as the browser would directly?
If not, how would I achieve this please?
Headers the detection script requires are: HTTP_ACCEPT, HTTP_X_WAP_PROFILE, HTTP_X_WAP_CLIENTID, HTTP_WAP_CONNECTION, HTTP_PROFILE, HTTP_X_OPERAMINI_PHONE_UA, HTTP_X_NOKIA_GATEWAY_ID, HTTP_X_ORANGE_ID, HTTP_X_VODAFONE_3GPDPCONTEXT, HTTP_X_HUAWEI_USERID, HTTP_UA_OS,
HTTP_X_MOBILE_GATEWAY, HTTP_X_ATT_DEVICEID, HTTP_UA_CPU
Many thanks.
Yes you can set the HTTP headers in your ajax call :
$.ajax({
url: 'YourRestEndPoint',
headers: {
'header1':'xxxxxxxxxxxxx',
'herader2':'xxxxxxxxxxxxxxxxxxxx',
'Content-Type':'application/json'
},
method: 'POST',
dataType: 'json',
data: YourData,
success: function(data){
console.log('succes: '+data);
}
});
Please find more information here :Add Header in AJAX Request with jQuery.
To get the value of the HTTP headers, use the following code :
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);
More information here
I was trying to do some test with Google Safe Browsing Lookup API.
$(document).ready(function(){
$("button").click(function(){
$.get("https://sb-ssl.google.com/safebrowsing/api/lookup", { client: "api", appver: "1.5.2", apikey: "MYAPI123", pver: "3.0", url:"www.ianfette.org" } )
.done(function(data) {
alert("Data Loaded: " + data);
});
});
});
But i cannot get a response from the server. I have tried with fopen in php and it works but i need it to do with jQuery and also to get the response code from the server for example 200 if the site is listed.
Maybe you can suggest and any PHP Solution.
$.get does an ajax request, which means that it is limited by the same origin policy, so you cannot access google.com from your domain.
To get around this, you probably need to implement a proxy url in php on your domain and request that with jquery.