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 nobody) -
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/DELETEa request without abody - Person reproducing needs to be using IE 11
Problem areas in our current code
Not comprehensive (just Ctrl + f: resource.save, resource.delete)
- Issue show service
deleteIssuable - MR widget service
cancelAutomaticMerge - MR widget service
removeWIP - MR widget service
removeSourceBranch - MR widget service EE
approveMergeRequest - MR widget service EE
unapproveMergeRequest - MR widget service EE
rebase - more if
PUT,PATCHalso have issues (needs to be tested)
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