Fine-Uploader - retry with "scaling" and "hideScaled" only sends original image - fine-uploader

I'm calling Fine-Uploader to upload images with client-side scaling, and I'm hiding the scaled images. If there's a bug in my server-side receiver CGI script then all uploads fail and the image shows a "Retry" button, but clicking it (after fixing the bug!) only causes the failed original image to be resent. The scaled images are lost. Here's the fine-uploader call. What am I missing to get it to resend the scaled images if they failed?
$('#fine-uploader-manual-trigger').fineUploader({
template: 'qq-template-manual-trigger',
request: {
endpoint: 'cgi/fine-uploader.cgi',
},
thumbnails: {
placeholders: {
waitingPath: PLACEHOLDERS+'waiting-generic.png',
notAvailablePath: PLACEHOLDERS+'not_available-generic.png'
}
},
// request client-size scaling - causes upload of "image (size).jpg" in addition to "image.jpg"
scaling: {
sizes: [
{ name: "thumb", maxSize: 200 },
{ name: "popup", maxSize: 600 },
],
hideScaled: true
},
autoUpload: false
});
$('#trigger-upload').click(function() {
$('#fine-uploader-manual-trigger').fineUploader('uploadStoredFiles');
});
};

From the scaled images documentation page:
Since they will not be represented in the UI, this means that they cannot be deleted, canceled, or manually retried via Fine Uploader's default UI. Failures of these scaled versions will obviously not be apparent to users by default if you elect to hide them from the UI.
If you want to manually retry hidden scaled images, you'll need to get a handle on their IDs and use the retry API method.

Related

fineUploader Failed in the Request To endpoint and the cause in onError Callback is UnKnown Reason

kindly i have to pages using fineUploader ,
the first page is working correctly but the second isn't : the response in debugging browser console is:
My Html Body will be existing here.
Simple upload request failed for 0
[Fine Uploader 5.11.8] Error when attempting to parse xhr response
text (Unexpected token < in JSON at position 0)
for the point one :(the request didn't reach the endpoint because i made a tester in the endpoint page if any script accessed it)
so the request in the first page is working and the same request with the same path in endpoint property isn't working in the second
i read many articles with the same error but all of them were not identifying correct endpoint path , which i did correctly and tested in the first Page.
var uploader = new qq.FineUploader({
debug: true,
element: document.getElementById('my-uploader'),
request: {
endpoint: "http://localhost/fineuploader/endpoint.php",
// endpoint: "http://localhost/fineuploader/endpoint.php",//commented to prove that i used //both of the relative and absolute paths
},
chunking: {
enabled: true,
concurrent: {
enabled: true
},
success: {
endpoint: "http://localhost/fineuploader/endpoint.php?done",
}
},
deleteFile: {
enabled: true,
endpoint: "http://localhost/fineuploader/endpoint.php"
},
retry: {
enableAuto: true,
showButton: true
},
form:{element:"FormId", },
callbacks: {
onError: function(id, name, errorReason, xhrOrXdr) {
alert(qq.format("Error on file number {} - {}. Reason: {}", id, name, errorReason));
},
});
The Answer of Mr Ray Nicholus Here was useful but i want to provide the solution in my case and my mistake, my problem was that in the first page i didn't provide action attribute in form tag and in the second i did , so when i provided in the second page the action of the form a different value than what is specified in
<form id="test" action="form.php">
request: {
endpoint: "http://localhost/fineuploader/endpoint.php",},
the requests were going to the action attribute value path(form.php) not for the above request value (endpoint.php).
It's really very simple, and there is no other answer to this question: either your endpoint is incorrect (and of course the response will be invalid too) or your endpoint is correct but your endpoint is not returning valid JSON. You'll need to look at the response closely to determine the issue.
In your case, your endpoint is returning HTML, not JSON. You'll have to fix this on your server.

Facebook profile image is not displayed with <Image>

I got an app where I have to show an user profile image.
Some users are logged in by Facebook, so we are saving their Facebook profile image and when I try to render this image with React Native Image component, the image is not displayed.
What I got:
<Image style={ styles.userImage } source={{uri: "http://graph.facebook.com/{userID}/picture?type=small" }} />
And styles:
userInfoContainer: {
flex: 1,
alignItems: 'center',
paddingTop: 30,
paddingBottom: 30,
borderBottomWidth: 1,
borderBottomColor: '#e5e5e5',
backgroundColor: '#ffffff',
},
userImage: {
height: 100,
width: 100,
borderRadius: 50,
marginBottom: 20,
},
I don't know if the problem is that this Facebook image URL doesn't have image extension.
Any help is welcome.
Thanks :)
The issue is that the facebook graph url is not the actual url for where that image is stored. It is a redirect. There is an issue out on the react-native github which is tracking a similar issue (301 redirect). It looks like it is partially solved (working for 301's on iOS).
https://github.com/facebook/react-native/issues/4940
Some more details about this if you're curious:
Facebook gives you the graph url, but actually stores the image elsewhere on a cdn. This lets facebook move assets around without breaking the facebook graph url that they document. The graph url will redirect to the actual url, which means that the graph url returns a 302 (non-permanent redirect).
For example, currently my profile pic would be queried using this url:
https://graph.facebook.com/207537292916369/picture?type=large
But it will redirect (currently) to this actual location:
https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/15940479_407531822916914_4834858285678282755_n.jpg?oh=a49a86e0e8042e3df27ce3dfe871b958&oe=59327225
Looks like you have to remove one set of quotes from the uri string.
I think the problems lies in the picture url redirection. If you add &redirect=false at the end of your url and you use the url fields in the data object shown, the image should show properly.
I don't know the main reason for that but this workaround should help, even though it means writing more code.
It is possible and easy do this (get user profile's picture) using the Facebook React Native SDK.
1) Import the useful classes for this from react-native-fbsdk.
import { AccessToken, GraphRequest, GraphRequestManager } from 'react-native-fbsdk'
2) Implement the Facebook Graph Request in your method, like 'componentDidMount', as an example.
try {
const currentAccessToken = await AccessToken.getCurrentAccessToken()
const graphRequest = new GraphRequest('/me', {
accessToken: currentAccessToken.accessToken,
parameters: {
fields: {
string: 'picture.type(large)',
},
},
}, (error, result) => {
if (error) {
console.log(error)
} else {
this.setState({
picture: result.picture.data.url,
})
}
})
new GraphRequestManager().addRequest(graphRequest).start()
} catch (error) {
console.error(error)
}
3) Use the value of this.state.picture where you need.
<Image source={ { uri: this.state.picture } } />
I would recommend pass it by props, instead of handling as a stateful resource, but it will depend of your needs.
For those showing up to this thread years later like me, the thing that fixed it for me was just changing the Facebook Graph URL from http to https. React Native was able to display it properly after that.

Is chunking.success.endpoint supposed to be called even when there is only a single chunk?

If I have chunking enabled and a success endpoint defined:
chunking: {
enabled: true,
concurrent: {
enabled: true
},
success: {
endpoint: "/FileUploadComplete"
}
},
The endpoint "/FileUploadComplete" is not hit unless the file is larger than the chunk size. Documentation (http://docs.fineuploader.com/features/concurrent-chunking.html) states that "Fine Uploader will send a POST after all chunks have been successfully uploaded for each file."
That is correct. If the file is not chunked, none of the chunking-related logic/options/endpoints apply.

Fineuploader taking too long to upload files in IE9

Hi I am using fineuploader 3.3.0 version.
I am facing problem with fineuploader in IE9. as fine uploader does not support sizeLimit in ie9.
I am checking the file size at server side with simple contentlength check if (this.Request.Files[0].ContentLength > 5242880).
but it took 1-2 mins to get this response. Also the 1.4 MB file is taking too long to upload.
Can some one please let me know what is causing it, following is the fineuploader code I am using:-
$('#restricted-fine-uploader').fineUploader({
request: {
endpoint: '/apm/api/job/UploadDocument/?category=' + JobDocuments.category + '&mode=' + JobDocuments.forceupload + '&jobid=' + job_manager_details.jobId
},
autoUpload: true,
text: {
uploadButton: 'Upload File'
},
multiple: false,
validation: {
allowedExtensions: ['doc', 'docx', 'xls', 'xlsx', 'pdf'],
sizeLimit: 5242880,
itemLimit: 1
},
showMessage: function (message) {
// Using Twitter Bootstrap's classes and jQuery selector and method
$('#restricted-fine-uploader').append('<div class="alert alert-error">' + message + '</div>');
}
}).bind('submit', function (event, id, fileName) {
$('#displaymessage').hide();
$('li. qq-upload-fail').hide();
job_manager_details.isuploading = 1;
// fileCount++;
}).bind('complete', function (event, id, fileName, responseJSON) {
$('li. qq-upload-fail').hide();
$('#displaymessage').hide();
job_manager_details.isuploading = 0;
if (responseJSON.success) {
// fileCount--;
ShowJobDocuments();
// if (fileCount == 0 && !$('div.alert-error').html()) {
$('#jobDocumentDialog').dialog("close");
// }
}
})
I just had the same issue and found one more clue.
The VM is incredibly slow (WinXP/IE8) while the network was a NAT'd but it became very fast as soon as it was switched to being bridged.
The speed of the upload should not be influenced by Fine Uploader in any noticeable way. All Fine Uploader does for non File API browsers, such as IE9 and older, is submit a <form> containing the file and related parameters. If you are noticing slow upload times, most likely something in your environment is the cause of the issue. You haven't provided any additional information about your environment, so I can't offer any advice on that front.
As you may already know, file size checking is not possible client-side in IE9 and earlier due to lack of File API support.

Extjs 4 (with a code for 3.4 below) downloading a file returned from a post request

I have seen questions slightly related to this, but none that answer my problem. I have set up an Ext.Ajax.request as follows:
var paramsStringVar = 'param1=1&param2=two&param3=something&param4=etc';
Ext.Ajax.request({
url: '/cgi-bin/url.pl',
method:'POST',
params:paramsStringVar,
timeout:120000,
success: function(response, opts){
var objhtml = response.responseText; //content returned from server side
console.log(objhtml);
}
});
This request retrieves the appropriate content from the backend. One parameter is outputType, which can take values {html, excel, csv}. When returning html to display I am able to handle and display it correctly. Now on to the problem...
When I set the outputType parameter to csv or excel, I get back the appropriate content as csv or tsv(excel) as requested. BUT, I don't want the content, I want a prompt to download the file(csv or excel). How can I have the browser auto prompt the user to download the file instead of just retrieving the text content within extjs?
Version 4.07 so I can't use any 4.1 only features
There seems to be no bulletproof solution but there are several approaches I would try:
1) Use an iframe instead of real XHR to POST data to the server, e.g. <form action="/something" target="myiframe"> where myiframe is the name of your hidden iframe. That way your form would use the iframe (not your main window) to submit data to the configured URL. Your server should set response header as application/octet-stream (or some ither MIME type for binary data) so the browser triggers download. Otherwise (if html returned in your case) you can just retrieve iframe's body innerHTML and display it to the user in UI. While using an iframe (or a new window) instead of XHR doesn't sound like the best idea, this solution seems to be the most reliable so far (and with best browser support).
Here is a slightly modified example from Ext.form.Basic docs page:
Ext.create('Ext.form.Panel', {
title: 'Basic Form',
renderTo: Ext.getBody(),
width: 350,
// Any configuration items here will be automatically passed along to
// the Ext.form.Basic instance when it gets created.
// *THIS* makes the form use a standard submit mechanism, not XHR
/**/standardSubmit: true,
// URL to submit to
url: 'save-form.php',
items: [{
fieldLabel: 'Field',
xtype: 'textfield',
name: 'theField'
}],
buttons: [{
text: 'Submit',
handler: function() {
// The getForm() method returns the Ext.form.Basic instance:
var form = this.up('form').getForm();
if (form.isValid()) {
// Submit the Ajax request and handle the response
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
},
// You can put the name of your iframe here instead of _blank
// this parameter makes its way to Ext.form.Basic.doAction()
// and further leads to creation of StandardSubmit action instance
/**/ target: '_blank'
});
}
}
}]
});
There are two key parameters here (lines marked with /**/):
standardSubmit: true config that you pass to your form will make it do a standard submit instead of XHR.
Passing a target parameter to the form's submit action. This feature is not documented but you can see it being used in Ext.form.action.Submit source code (all options that you pass to Ext.form.Basic.submit() method end up as parameters of Ext.form.action.* instance.
In the example code I put target: '_blank' to demonstrate that it works right away (will create a new browser window). You can replace it with the name of your iframe later but I suggest that you first test how your form submits data to a regular new window and then develop logic that creates and processes an iframe. You will have to process the result inside iframe yourself, thought. It's not that difficult, see Ext.data.Connection.upload() implementation as an example of iframe processing.
ExtJS actually already uses the iframe technique for file uploads. See Ext.data.Connection and Ext.form.field.Field.isFileUpload() for an idea of how it can work.
2) Suggested here: Using HTML5/Javascript to generate and save a file.
If you don't want to go the iframe way, you can try generate data URI from response data and navigate to that URI triggering download:
content = "Hello world!";
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
window.location.href = uriContent;
Again, mimetype is essential here. This worked for me, you should note, however, that browsers impose a size limit to data URIs (256Kb is a safe bet).
3) Another answer in the mentioned thread links to FileSaver.js library the implements the (abandoned?) w3 spec. Usage and demo here. It uses [BlobBuilder] to generate a blob of binary data that is further used to initialize downloads using one of several methods. While this solution seems to work, it uses deprecated APIs and may not be future-proof.
Below is my solution. This is how I have it currently working. The response generates a download/open prompt, based on a response type of text/csv. Note that no iFrame or reference to an iframe are needed. I spent a lot of time hung up on the need for an iFrame, which actually broke my solution. An iFrame is not needed to generate a download prompt. What is needed is a request(submittal) similar to this one, along with a backend generating the appropriate csv with text/csv response header.
var hiddenForm = Ext.create('Ext.form.Panel', {
title:'hiddenForm',
standardSubmit: true,
url: /cgi-bin/url.pl
timeout: 120000,
height:0,
width: 0,
hidden:true,
items:[
{xtype:'hiddenField', name:'field1', value:'field1Value'},
// additional fields
]
})
hiddenForm.getForm().submit()
The standardSubmit line is vital
You don't need to create a form panel and make it hidden in your extjs file. We can add a html form and on click of button in extjs file we can submit the form using the url. This will work both in IE as well as chrome browsers. Below is my code i tried and its working fine,
<form action="<%=fullURL%>/DownloadServlet.do" method="get" id="downloadForm" name="downloadForm" target="_self">
</form>
click:
{
fn: function()
{
document.getElementById('downloadForm').submit();
}
}
To get it working on ExtJS 3.4:
var hiddenForm = new Ext.FormPanel({
id:'hiddenForm',
region: 'south',
method: 'POST',
url: "/cgi/test.wsgi",
height: 0,
standardSubmit: true,
hidden:true,
items:[
{xtype:'hidden', name:'p', value:p},
{xtype:'hidden', name:'g', value:g},
// ...
],
});
linkThis = new Ext.Button({
text: 'Download this CSV',
handler: function() {
hiddenForm.getForm().submit();
},
maxHeight: 30,
});
Remember that in order to make it working, you should put the hiddenForm in any container (i.e. in the same Ext.Window of the button), for example:
risultatiWindow = new Ext.Window({
title: 'CSV Export',
height: 400,
width: 500,
....
items: [...., hiddenForm]
});

Resources