beestream's avatar

File upload working locally but not on production server

Hello, I have a site with a couple of forms, both of which has file inputs.

  • Both have multipart/form-data.
  • Both forms works on my dev-environment.
  • On the production server, only one of them works.
  • The request on non-working form does not contain any files (FileBag is empty)

Differences between the forms:

  • Working form has name="file[0]while non-working has name="post[comics][0][file][10]
  • Working form has file-field in a blade component. Non-working is generated with vuejs. (No errors.
  • Files are uploaded to different folders, but with identical permissions. But files are not even in the request, so that seems like the next step to me.

Has anyone encountered anything similar?

0 likes
7 replies
beestream's avatar
  -repository: PostRepository {#282}
  #container: Application {#3 ▶}
  #redirector: Redirector {#292 ▶}
  #redirect: null
  #redirectRoute: null
  #redirectAction: null
  #errorBag: "default"
  #dontFlash: array:2 [▶]
  #json: ParameterBag {#291 ▶}
  #convertedFiles: []
  #userResolver: Closure {#188 ▶}
  #routeResolver: Closure {#187 ▶}
  +attributes: ParameterBag {#290 ▶}
  +request: ParameterBag {#279 ▼
    #parameters: array:6 [▼
      "_method" => "PATCH"
      "_token" => "PWaSygDGJjxqiMQh8FwbERjZKPoVdjz0ubcFeck8"
      "title" => "Customers"
      "date" => "2017-12-31"
      "post" => array:1 [▶]
      "submit" => ""
    ]
  }
  +query: ParameterBag {#271 ▶}
  +server: ServerBag {#289 ▶}
  +files: FileBag {#288 ▼
    #parameters: []
  }
  +cookies: ParameterBag {#285 ▶}
  +headers: HeaderBag {#287 ▼
    #headers: array:14 [▼
      "cookie" => array:1 [▶]
      "accept-language" => array:1 [▶]
      "accept-encoding" => array:1 [▶]
      "referer" => array:1 [▶]
      "accept" => array:1 [▶]
      "content-type" => array:1 [▼
        0 => "multipart/form-data; boundary=----WebKitFormBoundaryhcH6oePYf1iapqVk"
      ]
      "user-agent" => array:1 [▶]
      "upgrade-insecure-requests" => array:1 [▶]
      "origin" => array:1 [▶]
      "cache-control" => array:1 [▶]
      "pragma" => array:1 [▶]
      "content-length" => array:1 [▶]
      "connection" => array:1 [▶]
      "host" => array:1 [▶]
    ]
    #cacheControl: array:1 [▶]
  }
  #content: ""
  #languages: null
  #charsets: null
  #encodings: null
  #acceptableContentTypes: null
  #pathInfo: null
  #requestUri: null
  #baseUrl: null
  #basePath: null
  #method: null
  #format: null
  #session: Store {#215 ▶}
  #locale: null
  #defaultLocale: "en"
}
WebKenth's avatar

Why would there be differences in the form, local vs production server?

Doesn't that just beg for bugs to appear?

Check chrome dev tools, network log to see what is actually being sent

beestream's avatar

There are no differences in the forms, production vs local. Sorry that was a bit unclear. The difference are between the forms in the different parts of the application.

beestream's avatar

Devtools says no different than request above. Empty file fields, correct otherwise

WebKenth's avatar

How are you sending the request? are you grabbing the FormData via javascript or is it a submit button that does it all?

1 like
beestream's avatar

One step closer. Seems to be a front end problem. I have a button that clicks a file input. A FileReader shows a preview, but after preview is shown, the file input is emptied. Thanks @WebKenth, I will post code to show the problem soon. ( I hope ) =)

beestream's avatar

Did not figure this out and I solved it by doing a solution that's a bit harder for the user with forms and requests and page reloading. We did figure out part of the problem. In the ImagePicker.vue compoenent the file input was emptied during filereader.onload event. Seems to be connected to setting data variables on the vue instance onload. Don't understand why. Anyway, here's the component:

    
    <section class="filePicker image">

        <div v-if="backgroundImage" class="imagePlaceholder" :style="'height:200px; background-image: url(' + backgroundImage + '); background-position: center center; background-size:contain'"></div>
        <div class="buttons">
                <div v-if="setImage">
                    <p>{{setImage[0].alt_text}}</p>
                    <button @click.prevent="deleteFile(image[0].id)"  class="btn btn-outline delete">Ta bort bild</button>
                </div>
                <div v-else>
                    <input class="imageInput" :id="fileInputID" type="file" value="" :name="namespace + '[file]'" @change.stop="updateBackground" style="display:none;" />
                    <button @click.prevent="clickFileInput" class="btn btn-outline chooseFile">Välj bild</button>
                    <input type="text" value="" :name="namespace + '[alt_text]'" placeholder="Bildtext"/>
                </div>
        </div>

    </section>
</template>
<script>
    export default {

        props: {
            image: {default: null},
            namespace: {default:null}
        },

        data() {
            return {
                imageDeleted: false,
                backgroundImage: null,
                setImage: null,
                fileInputValue: ''
            }
        },

        computed: {
            fileInputID() {
                return this.namespace + 'input_id';
            }
        },

        methods: {
            deleteFile(id) {
                this.$http.delete('/files/'+id+'/ajax').then( function(response) {
                    if (response.status == 200) {
                        this.setImage = null;
                        this.backgroundImage = '';
                    }
                });
            },
            clickFileInput () {
                document.getElementById(this.fileInputID).click();
            },
            updateBackground (e) {
                var reader = new FileReader(),
                    file = e.target.files[0];
                this.fileInputValue = fileName;

                reader.onload = function (event) {
                    this.backgroundImage = event.target.result;
                }.bind(this)

                reader.readAsDataURL(file);
            },
            getUrlFromImage() {
                var url = '/files/' + this.image[0].id + '/medium';
                return url;
            }
        },
        mounted()  {
            if (this.image.length) {
                this.setImage = this.image
                this.backgroundImage = this.getUrlFromImage();
            }
        }
    }
</script>


Please or to participate in this conversation.