image url loads in browser bar, but not using axios GET - ajax

I have a URL that was created using AWS S3 signed URL method. There is an image object at the URL. I verified this by copying the "url" value below and pasting into a browser address bar. NOTE: this link has probably expired, but it did show a JPEG of dogs when copied into a browser's address bar!
I am attempting to get the URL as base64 text using the function below. When I pasted the URL into my web browser's address bar, I see the image just fine. However, the code below is not getting past the "axios.get" stage.
This is the error that I'm seeing (remember: pasting into a web browser shows the image just fine!)
...from origin '[origin]' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Here's the original script I'm running:
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>
const test = getImageAsBase64 = async (url) => {
const { data } = await axios.get(url, {
responseType: 'arraybuffer'
})
return Buffer.from(data, 'binary').toString('base64');
}
const url = 'https://some-aws-alias.s3.amazonaws.com/3752966330/1972367600/87284909-f46c-4700-a0cb-7f09e7898629/puppies.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAQGBDVNXFTNE6JIXM%2F20221129%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20221129T055411Z&X-Amz-Expires=3600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjED4aCXVzLWVhc3QtMSJIMEYCIQDyG9vvP8X8YzMj0egEFEsouzbYoCzYW03HvJSA0eyzvwIhAIl7m8YA8O4a9mPGkBMIfO950lbJivWrXLqk9NvG%2FiNTKo0DCFcQABoMMDEyOTU5NzA2NTcxIgwS0wXWzm%2FR2tJN19Qq6gIcMLFiH9V6vSQ8hF3C7EgZgiQn1E7y5lUDu4%2BkdObQy2AXxzlObc9YrWo9qj3xtzLAqx3yk3OCV2YgQ913EpwivdpyX2qudPFdgCExxoZeKOoVjNnQmC8hiT%2BkiKE%2FilJMZnmU4haXxBayP7TfFKjig5KAYJWQjKkPpbBJCuPkpC6rjVlaYnYQfcTPlDy4BRhgRC1D%2FLz9V32ra3egQhIpI%2BlFmENu%2BkQErJZ7okhsCVTkK8pk8UT9qsxFiL7Z7wp6xKSEf%2BhLERqGBPVgKScywPJmLOIH%2Bkoqjtwpqj19p5cqO5L%2FuP7dC22QxhbjeLuYasseFax%2FAysC7zfAK3JnFLZHGPC0nkfZ614ACIiaes6pMLLfX5azusan54lmPIJWU8xSA5zm32gQINH6Mk6SiOvHub5QBUFfdw5fjmAnr0Dv943xvF8hiHPdO5jsmEAYQp%2BcAm9HE6Ue7Y2dTG3TtOFMI%2Fm73PWYizCgvJacBjqcAV2Sym94YbMLDParZkOBKWOfFWhPkbrVPqDu1P45YChoieepeCDvck5FNu%2F9Lw3W2HR%2FvcGMQFWOzkYWMYUjAIhiDV03D%2BY7fpglA6TNVjQjsdvUz15yPL8yDBPHFCMMdcjwf%2F2zPDyqVYEsbLhBRJZqEkpqy6SPBIDplTL3bYLORZAm%2B9aOyHHJWH7FcSqTmKfUgcdqJphGkxNv0Q%3D%3D&X-Amz-Signature=99fc4c8dbc8ad3b0a72396688ffd1e7fa82566c520e09b908d8fac3d35cafc23&X-Amz-SignedHeaders=host';
const base64Version = getImageAsBase64(url);
</script>
</html>

Related

POST request is working okay on localhost but on server it is showing as a get request

Actually, I'm sending a post request to save the templates. It is working fine if I send the post request on Local. But if i make a build and send a post request it is not allowing me to send post request and instead showing me get request in network.
The static urls below are working fine.
const response = await axios.post('https://applicationname/api/template', {
template_json: templateJson,
name: name,
type: refinedJson.type,
ImageBase64: await image
}).catch((error) => {
localStorage.setItem('Save-temp', error.response.data.message)
showToastError()
localStorage.removeItem('Save-temp')
toggleFaq(true)
});
The one which causes errors:
const response = await axios.post('/api/template', {
template_json: templateJson,
name: name,
type: refinedJson.type,
ImageBase64: await image
}).catch((error) => {
localStorage.setItem('Save-temp', error.response.data.message)
showToastError()
localStorage.removeItem('Save-temp')
toggleFaq(true)
});
.env
APP_URL= http://localhost

Download file with AJAX using Dart

Is it at all possible to download a file upon an ajax request?
Does it matter if it's same domain / cross domain?
I know it can be done upon redirecting the browser to a URL and setting relevant headers, but was wondering if it can be done when doing an ajax request.
I'm POSTing JSON as the Request Payload to a URL and based on the content of the JSON, I want to send back a specific file.
client.post(url, body: request, headers:{"Content-Type":"application/json"}).then((res) {
if (res.statusCode == 200) {
if ("application/json" == res.headers["content-type"]) {
// parse JSON here
} else {
// download the content if Content-Disposition is set
}
}
}).whenComplete(() {
client.close();
}).catchError((exception, stacktrace) {
print(exception);
print(stacktrace);
showErrorMessage("An Error Occurred");
});
I can see the the correct headers coming back for downloading a PDF, but it's not doing anything if I receive these headers via an AJAX response.
Update - clarifying:
If you click this link, it will do a GET request to Github and download the file: https://github.com/dartsim/dart/archive/master.zip
I'm trying to download the file using a POST request via Dart's BrowserClient.post.

Django Angular Authentication CSRF cached template

I am getting status code 403 when I try to log in after successfully being logged in and logged out.
Client side is written in Angular and server side is in Django.
This goes as follows:
Client requests url '/' fetches main HTML template with all required static files ( angular, bootstrap, jQuery sources and angular sources defined by me) with
<div ng-view></div> tag into which further templates will be inserted.
Via $location service is redirected to url '/#/login'
This rule from $routeProvider is executed once '/#/login' is hit:
$routeProvider.when('/login', {
templateUrl: 'login.html'
});
'login.html' is served by django view and form for logging in is rendered to the user
User logs in successfully providing proper credentials
Then user logs out, by clicking on a button, which fires '$http.get(
'/logout/'
);' and then is redirected to url '/#/login'
Here is the problem. When user fills in credential form and sends 'POST' request, 403 is returned. I thought that it is, because this routing is done only by angular and since 'login.html' template has already been requested it has been catched and can be served without hitting backend, but after logging out currently possesed CSRF cookie is stale, so that's why I am getting 403. So I tried to remove that template:
logout: function(){
var forceLoginTemplateRequest = function(){
if( $templateCache.get('login.html') !== 'undefined'){
$templateCache.remove('login.html');
}
};
var responsePromise = $http.get(
urls.logout
);
responsePromise.success(forceLoginTemplateRequest);
return responsePromise;
}
After doing that I could see client side requesting 'login.html' template always after logging out, so I thought I could provide CSRF cookie when serving that template from backend:
#urls.py
urlpatterns = patterns(
'',
...
url(r'^$', serve_home_template),
url(r'^login.html$', serve_login_template),
url(r'^login/', login_view, name='login'),
url(r'^logout/', logout_view, name='logout'),
...
)
#views.py
#ensure_csrf_cookie
def serve_login_template(request):
return render(request, "login.html")
#ensure_csrf_cookie
def serve_home_template(request):
return render(request, 'home.html')
But still it doesn't work and I am getting 403 when trying to log in after logging out. The only way I managed it to work is to simply refresh the page so that every single file, whether template or source file is requested again from the backend and CSRF cookie is updated with them.
Here is my app's run section for making sure CSRF cookie is sent with every request:
mainModule.run(['$http','$cookies', '$location', '$rootScope', 'AuthService', '$templateCache',
function($http, $cookies, $location, $rootScope, AuthService, $templateCache) {
$http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
$rootScope.$on( "$routeChangeStart", function(event, next, current) {
if ( !(AuthService.isLoggedIn() == "true")){
$location.path('/login');
}
});
}]);
This could be a cache problem. Try to add the never_cache decorator to all your views:
from django.views.decorators.cache import never_cache
...
#ensure_csrf_cookie
#never_cache
def serve_login_template(request):
return render(request, "login.html")
...
I solved this problem by setting X-CSRFTOKEN header in $routeChangeStart event.
I don't exactly know how module.run phase works, but it seems that when certain event defined within it occurs everything what is defined outside this event's handler body isn't executed.
mainModule.run(['$http','$cookies', '$location', '$rootScope', 'AuthService',
function($http, $cookies, $location, $rootScope, AuthService) {
$http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
$rootScope.$on( "$routeChangeStart", function(event, next, current) {
// Added this line
$http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
if ( !(AuthService.isLoggedIn() == "true")){
$location.path('/login');
}
});
}]);
This works together with removing 'login.html' template from $templateCache.
Instead of removing templates on client side with $templateCache service it is also possible to set your server to serve templates and set following headers:
Cache-Control: no-cache, no-store, must-revalidate
Pragma : no-cache
Expires : 0
Another way of dealing with this problem is to simply force page refresh, however I don't like this approach, since this is not pro-single-page-app approach. :)
One solution could be to read the current, fresh csrftoken directly from the cookie and then update the stale cookie using javascript.
var fresh_token = document.cookie.match('csrftoken=([a-zA-Z0-9]{32})

using img templats with ngSrc sends text/html instead of image/gif when data array is loaded via $http

I have a template like this:
<img class="picto"
ng-repeat="module in modules"
ng-src="{{module.Source}}"
title="{{module.Title}}"
ng-click="module.handler();"/>
When I set the $scope.modules array using static code, everything works fine, and the images are fetched via GET using media type "image/gif" (for gif files). However, when I retrieve the same array using $http.get() - see the code below -, angular tries to retrieve the images using media type "text/html" which results in an 404 error:
$http.get('/api/modules', {})
.success(function (data) {
$http.defaults.get = { 'Content-Type': 'image/gif' }; // apparently useless
$scope.modules = data;
for (var module in $scope.modules) {
$scope.modules[module].handler = function () { alert(this.Id); };
}
delete $http.defaults.get; // ...useless
});
Trying to add a header default did not help either (// apparently useless). Can you see what's wrong?
Try it with Accept: 'image/gif' instead of Content-Type: 'image/gif'.
The Content-Type header describes the data format you are sending to the server. The Accept header describes the data formats you accept in response from the server.

Django: relative url not working with post calls in ajax

I am trying to use relative url with a post ajax call as follows:
Current url path:
http://localhost:8000/customer/0/location/0/user/0/
I need to change to different directoy.
var absolute = "http://localhost:8000/customer/0/location/0/line_group/addLine/2/";//+phone_id;
var relative= "../../line_group/addLine/1"
$.get(relative,function(data){
//this works
alert(data);
});
$.ajax({
type: "POST",
url: relative,
data: "test=test1",
error:function(data){
//throws error when using relative path
alert('error');
},
success:function(data){
// works fine when using absolute path
alert('success');
}
});
//same thing using just post
$.post(relative,test,function(data){
//Error on relative path
alert(data);
return false;
});
For my get calls both, absolute and relative url, return data.
But for POST call, when I use relative url, I get internal server error.(absolute URL works fine)
I do not think it has got to do with CSRF, as in my view I have also include #csrf_exempt for test purposes.
(I have included https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax in request)
The chrome debugger gives me the following error message on the post call with relative URL.
Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR) http://localhost:8000/customer/0/location/0/line_group/addLine/1
However as you can see it does provide me the complete url link, which I want to access.
And when I click directly on the link, I get the data of the page.
The view is really simple:
#csrf_exempt
def addNewLine(request, customer_id, location_id, phone_id,**kwargs):
error_msg = u"No POST data sent."
context = {}
return render_to_response('line_group/mytest.html', context)
Any body has any suggestion, as to why the relative url path fails on POST call?
Thanks in advance..
In Chrome Network section you can preview the error explanation if you have DEBUG=True.
As you have no slash at the end of var relative= "../../line_group/addLine/1", it might be that CommonMiddleware redirects your request. Set APPEND_SLASH = False in project settings if you want to keep your URL as it is.

Resources