Skip to content

Vue Resource throwing JSON parsing errors with IE (no body)

With IE 11, when using vue-resource for POST/DELETE requests without a body, the backend will throw a 400 error response from trying to parse undefined as JSON.

Problem methods

  • GET (N/A no body)
  • POST
  • PUT
  • PATCH
  • DELETE

In Chrome, XHR seems to ignore undefined and not send it through to the body. In IE 11, it seems to pass it through.

I think we have only had 1 report around this area because there are so many criteria to be met:

  • Feature has to be using Vue and vue-resource
  • Request needs to be a POST/DELETE a request without a body
  • Person reproducing needs to be using IE 11

Problem areas in our current code

Not comprehensive (just Ctrl + f: resource.save, resource.delete)


Solutions

Switch to axios

This is the current strategy

  • account
  • balsamiq_viewer
  • blob
    • blob/notebook
  • boards
  • common
  • common_vue
  • cycle_analytics
  • commit_pipelines
  • deploy_keys
  • docs
  • diff_notes
  • environments
  • environments_folder
  • filtered_search
  • graphs
  • graphs_charts
  • graphs_show
  • group
  • groups
  • groups_list
  • help
  • how_to_merge
  • issue_show
  • integrations
  • job_details
  • locale
  • main
  • merge_conflicts
  • monitoring
  • network
  • notebook_viewer
  • notes
  • pdf_viewer
  • pipelines
  • pipelines_charts
  • pipelines_details
  • pipelines_times
  • profile
  • project_import_gl
  • project_new
  • prometheus_metrics
  • protected_branches
  • protected_tags
  • registry_list
  • ide
  • sidebar
  • schedule_form
  • schedules_index
  • snippet
  • sketch_viewer
  • stl_viewer
  • terminal
  • u2f
  • ui_development_kit
  • raven
  • vue_merge_request_widget
  • test
  • two_factor_auth
  • users
  • performance_bar
  • webpack_runtime

Upgrade vue-resource

This hasn't been scouted out but it is possible that the latest version has this fixed up or we could go fix it up 😉

Ignore undefined request body on the BE

We could ignore undefined request body passed to the BE and not try to parse.

Adding an interceptor

Add an interceptor that changes the request to Content-Type: text/plain if there aren't any parameters passed in.

Another sorta-workaround is passing '{}' as the body which works for a POST request but does not work in a DELETE request because vue-resource translates all body arguments over to URL query params.

Use Content-Type: text/plain

Passing the Content-Type: text/plain header to vue-resource whenever making a request that doesn't have a body works because Rails doesn't try to parse the body as JSON. This isn't a very good solution because it requires knowledge of this pitfall and is manual process to be forgotten.

this.someResource.save({}, {
  headers: {
    'Content-Type': 'text/plain',
  },
})

We did this here as a hotfix for approvals, https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2306

More ideas welcome 😀


cc @brycepj @jschatz1 @filipa @iamphill @jneen @smcgivern

Edited by Eric Eastwood