JavaScript MISBEHAVING -> CROSS ORIGIN RESOURCE EXCEPTION - javascript

After long research and debugging i realized java-script was not the problem, I was rather having a cross origin resource exception which was thrown because some how the ajax request could not read my server script or rather did not have permission to access my server script.
So i tried the following codes below but still the same issue, I placed the issue in red block blow, my java script is also below and my server script
$('#send').on('click', function(e) {
var name = $('#name').val();
var email = $('#email').val();
var message = $('#message').val();
alert("sending " + name + email + message);// this part is now working fine
$.ajax({
type: "POST",
url: "https://xxxxxx/xxxxx/php/contact/maincontact.php",
data: {
nme: name,
ema: email,
msg: message
},
dataType: 'json',
timeout: 10000,
async: true,
cache: true,// I removed the header which used to here before
error: function(jqXHR, textStatus, errorThrown) {
alert("error : " + errorThrown + " text :" + textStatus + " j :" + jqXHR.status);
alert(jqXHR.responseText);
},
success: Succeeded
});
});
function Succeeded(result) {
alert("Successing");
var data = JSON.parse(result[0]);
try {
$('#name').val(" ");
$('#email').val(" ");
$('#message').val(" ");
if (data == true) {
alert("We will Contact you shortly");
} else {
alert("OOpps! something went wrong");
}
} catch (e) {
alert("You may not enter " + e);
}
}
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxxxxxxx/xxxxxx/php/contact/maincontact.php. (Reason: missing token 'access-control-allow-origin' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).
<!-- php codes -->
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
require_once('contact.php');
if(!empty($_POST)){
$addcase = new contact();
$data['vlu'] = $addcase->add($_POST['nme'], $_POST['ema'], $_POST['msg']);
echo json_encode($data);
}else{
echo "Not properly parsed";
}
?>

The error message says:
missing token 'access-control-allow-origin' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel
So when you make the request you are trying to put access-control-allow-origin in the headers. (The message means that browser is asking the server if it is allowed to send that header in cross-origin Ajax and the server isn't saying that it is OK to do that).
This doesn't make any sense. Access-Control-Allow-Origin is a response header. There is no reason to put it on the request.
Now, the code you've provided doesn't try to set that header. This suggests that elsewhere in your code you are trying to set it universally (probably via ajaxsetup).
You need to find the point where you try to set it and remove that code.

Related

GoogleDrive API (javascript): no file download because of CORS

With this code, before an year about i could get the file via XMLHttpsRequest.
Now this do not more work, because of the error:
Access to XMLHttpRequest at 'https://drive.google.com/uc?id=1zGxNBh-YTAXu74v855l2b_LPmLUaomqZ&export=download' from origin 'https://encrypt.pdfzorro.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Is there a way at now, to get the file via javascript. I can not use any server solution, the file should go direct from googleDrive to the browser from the user.. without go on a server (with php e.g.) first.
function downloadFileContent(fileId){
gapi.client.request({
'path': '/drive/v2/files/' + fileId,
'method': 'GET',
callback: function ( theResponseJS, theResponseTXT ) {
var myToken = gapi.auth.getToken();
var myXHR = new XMLHttpRequest();
myXHR.open('GET', theResponseJS.downloadUrl, true );
myXHR.responseType = 'arraybuffer';
myXHR.setRequestHeader('Authorization', 'Bearer ' + myToken.access_token );
myXHR.onreadystatechange = function( theProgressEvent ) {
if (myXHR.readyState == 4) {
// 1=connection ok, 2=Request received, 3=running, 4=terminated
if ( myXHR.status == 200 ) {
// 200=OK
cossole.log(myXHR.response);
}
}
}
myXHR.send();
}
});
}

XMLHttpRequest endpoint blocked while signing S3 request because no HTTPS, eventhough everything is on HTTPS

I am trying to sign a huge video upload, because I want to upload it directly to S3. It works on localhost, but on my live site it fails to sign the request because of:
Mixed Content: The page at 'https://www.example.com/profile' was loaded
over HTTPS, but requested an insecure XMLHttpRequest endpoint
'http://www.example.com/sign_s3/?file_name=17mbvid.mp4&file_type=video/mp4'.
This request has been blocked; the content must be served over HTTPS.
I am hosting everything on heroku, every page is already using HTTPS and its not possible to open it in HTTP, because I redirect all traffic to HTTPS. I am using the letsencrypt SSL certificate.
So far I have no idea where to look, the only information I found, is that I need a valid SSL certificate, which I have.
Here is the JS function:
function getSignedRequest(file) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/sign_s3?file_name=" + file.name + "&file_type=" + file.type);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('got signed request');
var response = JSON.parse(xhr.responseText);
console.log(response);
console.log('uploadFile', response.url)
uploadFile(file, response.data, response.url);
} else {
console.log("Could not get signed URL.");
}
}
};
//console.log('send');
xhr.send();
}
Right after the error in the console I see this console log:
Could not get signed URL.
which means it fails here:
if (xhr.status === 200)
On the server:
#app.route('/sign_s3/', methods=["GET", "POST"])
#login_required
#check_confirmed
def sign_s3():
if "localhost" in request.url_root:
file_name = str(current_user.id) + "local-profil-video." + request.args.get('file_name').split(".")[-1]
else:
file_name = str(current_user.id) + "-profil-video." + request.args.get('file_name').split(".")[-1]
file_type = request.args.get('file_type')
session = boto3.Session(
aws_access_key_id=app.config['MY_AWS_ID'],
aws_secret_access_key=app.config['MY_AWS_SECRET'],
region_name='eu-central-1'
)
s3 = session.client('s3')
presigned_post = s3.generate_presigned_post(
Bucket = 'adultpatreon',
Key = 'videos/' + file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{"acl": "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)
if current_user.profile_video != None:
delete_file_from_aws("videos/", current_user.profile_video)
setattr(current_user, "profile_video", file_name)
db_session.commit()
return json.dumps({'data': presigned_post, 'url': 'https://s3.eu-central-1.amazonaws.com/mybucket/' + 'videos/' + file_name})
After many hours of researching I decided to rebuild this function and use AJAX get, which I am more familiar with. I also changed the way I pass/recieve the query string arguments to the best way, which is actually used in flask/python.
function getSignedRequest(file) {
$.ajax({
url : "/sign_s3/" + file.name + "/" + file.type,
type : "get",
success : function(response) {
console.log("success file up, follow", response);
var json_response = JSON.parse(response);
console.log(json_response);
uploadFile(file, json_response.data, json_response.url);
},
error : function(xhr) {
console.log("file up failed", xhr);
}
});
}
And on server side I changed how file.name and file.type are recieved:
# Sign request for direct file upload through client for video
#app.route('/sign_s3/<path:file_name_data>/<path:file_type_data>', methods=["GET", "POST"])
#login_required
#check_confirmed
def sign_s3(file_name_data, file_type_data):
#etc...
Now it works perfectly. I think they way I was recieving the query string arguments on the server was not correct, probably it would also work with the old getSignedRequest function (untested).

Download Google Drive file from url and send with post to backend

I am trying to download a file from an url (chrome drive file) in javascript; and want to send it to my backend (php - laravel).
var url = file.downloadUrl !== undefined ? file.webContentLink : file.exportLinks['application/pdf'];
console.log(url) // if I go to url, it downloads the file
if (url !== undefined) {
var remote = new XMLHttpRequest();
remote.open('GET', url);
remote.setRequestHeader('Authorization', 'Bearer ' + gapi.client.getToken().access_token);
remote.setRequestHeader('Access-Control-Allow-Origin', '*');
remote.onload = function(e) {
vm.handle_download(remote.responseText, file, 200); // do something with the fetched content;
};
remote.onerror = function(e) {
vm.handle_download('error response', null, remote.statusText);
};
remote.send();
} else vm.handle_download('no downloadable url', {
file: null,
status: 'error'
});
and on handle
handle_download: function (content, file, status) {
if (status !== 200) {
console.log('error occured on status')
return;
}
}
Failed to load https://drive.google.com/uc?id=1D12321ofd4CNG-m9_Mp4aiDcnibNf&export=download: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://test.dev' is therefore not allowed access.
This is an intended behavior due to same origin policy in the web. Since you're doing this for testing purposes, try this Allow-Control-Allow-Origin chrome extension.
You can read more about how to implement this in Using CORS tutorial.
This SO post may also offer additional insight.

Cross Origin Resource Sharing Issue with jQuery on https secure url?

I'm having a slight issue with a cross site origin request. I'm sure it is a simple fix.
Console error:
XMLHttpRequest cannot load https://subdomain.example.com/social/disqus. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.example.com' is therefore not allowed access.
js script causing the issue:
window.onload = function(){
//jQuery AJAX GET Method on Disqus Threads
$.ajax({
type: 'GET',
url: 'https://subdomain.example.com/social/disqus',
contentType: 'application/json; charset=utf-8',
success: function(threads) {
var len = Object.keys(threads.response).length
for (i = 0; i < len; i++){
if (threads.response[i].posts == 0 || threads.response[i].posts != 1) {
$('#' + threads.response[i].identifiers).html(threads.response[i].posts + " Comments ");
} else {
$('#' + threads.response[i].identifiers).html(threads.response[i].posts + " Comment ");
}
}
},
error: function() {
console.log("Aw, snap!");
}
});
};
I'm forcing redirects in Apache for both - this may be an issue, but it looks like the CORS request is being fired from a https:// valid site to another https:// valid site... url in the ajax request is definitely https.
I'm wondering if I am missing something from $.ajax ?

How to detect if ajax error is Access-Control-Allow-Origin or the file is actually missing

My question is NOT about how to solve the Access-Control-Allow-Origin issues. This errors will happen sometimes when performing requests, and other times the url's might be outdated. But I want to print different messages for the user depending on the different errors.
Currently I have the following code:
$.ajax(
{
url: link,
type:'HEAD',
timeout: 2000,
error: function(request, status, message)
{
console.log('ajax error');
console.log(request);
console.log(status);
console.log(message);
openPopUp("There was an error accessing the image. It can be because the address is invalid, "+
"or because the server where the image is stored is not allowing direct access to the images.");
},
success: function()
{
// More stuff here
}
});
Looking at the console it's easy to see if the file was actually missing, or if it was an Access-Control problem. But i'd like to print out two different messages to the user saying exactly what the problem was. Looking at the variables in error: function(request, status, message) they do not change, both cases result in a 404 error. Is there some other was to do this so that I can know what the problem was?
Thank you in advance for the attention.
Your browser console shows you
XMLHttpRequest cannot load http://www.google.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mysite.com' is therefore not allowed access.
but you cannot access this information yourself with JavaScript alone. When a browser detects a CORS violation, it will discard the header information as a matter of protocol.
One solution that works is to inspect the response headers using server-side code and pass the results back to your client page. For example, if the ajax request fails, you could call this script (let's call it cors.php) and know for certain if it contains "Access-Control-Allow-Origin" or not.
Example:
cors.php?url=http://ip.jsontest.com
cors.php?url=http://www.google.com
returns
Access-Control-Allow-Origin: *
None
Thus, you can do the following in your JavaScript code:
$.ajax({
url: "http://www.google.com",
timeout: 4000,
statusCode: {
404: function() {
// Simple not found page, but not CORS violation
console.log(this.url + " not found" );
}
}
})
.fail(function(jqXHR, textStatus) {
// Empty status is a sign that this may be a CORS violation
// but also check if the request timed out, or that the domain exists
if(jqXHR.status > 0 || jqXHR.statusText == "timeout") {
console.log("Failure because: "+jqXHR.status+" "+jqXHR.statusText+" error");
return;
}
// Determine if this was a CORS violation or not
console.log("Checking if this is a CORS violation at - " + this.url);
$.ajax({
url: "http://myserver.net/cors.php?url=" + escape(this.url),
})
.done(function(msg) {
// Check for the Access-Control-Allow-Origin header
if(msg.indexOf("Access-Control-Allow-Origin") >= 0) {
console.log("Failed bacause '" + msg + "'");
} else {
console.log("Failed bacause of CORS violation");
}
});
})
.done(function(msg) {
// Successful ajax request
console.log(msg);
}); /* Drakes, 2015 */
Customize this PHP script for your own needs:
<?php
/* cors.php */
$url = $_GET["url"];
if(isset($url)) {
$headers = getHeaders($url, "Access-Control-Allow-Origin");
header("Access-Control-Allow-Origin: *"); // Allow your own cross-site requests
echo count($headers) > 0 ? $headers[0] : "None";
}
// Get the response headers, only specific ones
function getHeaders($url, $needle = false) {
$headers = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // Only get the headers
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header_line) use(&$headers, $needle) {
if(!$needle || strpos($header_line, $needle) !== false) {
array_push($headers, $header_line);
}
return strlen($header_line);
});
curl_setopt($ch, CURLOPT_URL, $url);
curl_exec($ch);
return $headers;
} /* Drakes, 2015 */
You should be able to read the response header from the request object:
var acao = request.getResponseHeader('Access-Control-Allow-Origin');
then output the appropriate error based on whether the header exists and whether your url is in the value.

Categories

Resources