dropbox-sdk-js icon indicating copy to clipboard operation
dropbox-sdk-js copied to clipboard

CORS preflights on every call

Open kennellink opened this issue 7 years ago • 10 comments

It looks like every call the SDK makes requires a CORS preflight - very inefficient. On this page I found this: Browser-based JavaScript and CORS pre-flight requests

When browser-based JavaScript code makes a cross-site HTTP request, the browser must sometimes send a "pre-flight" check to make sure the server allows cross-site requests. You can avoid the extra round-trip by ensuring your request meets the CORS definition of a "simple cross-site request". •·Use URL parameters arg and authorization instead of HTTP headers Dropbox-API-Arg and Authorization. •·Set the Content-Type to "text/plain; charset=dropbox-cors-hack" instead of "application/json" or "application/octet-stream". •·Always set the URL parameter reject_cors_preflight=true. This makes it easier to catch cases where your code is unintentionally triggering a pre-flight check.

I hop the above helps.

kennellink avatar Mar 07 '17 07:03 kennellink

Thanks! I'll send this along to the team.

greg-db avatar Mar 07 '17 19:03 greg-db

Thanks for reporting (more like telling us how to fix) @kennellink, I'll look at this.

pran1990 avatar Mar 08 '17 18:03 pran1990

Is this solved yet? I can't use the SDK to upload bigger files just because of this errors:

Refused to set unsafe header "accept-encoding"
Refused to set unsafe header "user-agent"
Refused to set unsafe header "content-length"

Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

vladejs avatar May 03 '17 14:05 vladejs

@vladejs I don't have an update on this issue, but I don't believe this should be preventing large file uploads from completing.

Please open a new issue with the steps to reproduce the issue, including the relevant code, so we can look into it. Thanks in advance!

greg-db avatar May 03 '17 18:05 greg-db

@greg-db , I followed an example posted on #80 to upload big files using sessions, and got the above errors. The docs barely explain the simplest upload use case, so yeah, I just can't upload large files using the SDK.

Is unbelievable that such company like Dropbox doesn't have a clear guidance for developers to use their platform. I am paying for a 1TB storage for nothing, 'cause my app can't upload a 151 mb file.

If it's doable, why not explain how?

vladejs avatar May 03 '17 18:05 vladejs

@vladejs Thanks for the feedback. Using upload sessions as described there is the right way to upload large files. I can't seem reproduce the error you're seeing though, so please open a new issue with details so we can help.

greg-db avatar May 03 '17 21:05 greg-db

P.S. I found the same text/hint for eliminating pre-flights in the Dropbox API v2 documentation near the top under Request and response formats | Browser-based JavaScript and CORS pre-flight requests. It looks like pre-flights are adding almost 1/4 second (on average) to each API call.

kennellink avatar Oct 03 '17 19:10 kennellink

Just checking in to see if there's an intention to fix this since there seems to be no activity on this issue. The official Dropbox HTTP documentation in the section "Browser-based JavaScript and CORS pre-flight requests" suggests avoiding the pre-flight and explains how to do it, so I had been hoping that the JavaScript SDK would implement it. Thanks!

aryehsanders avatar Sep 01 '22 15:09 aryehsanders

@aryehsanders I don't have an update on this currently.

greg-db avatar Sep 01 '22 17:09 greg-db

As a workaround, new Dropbox() accepts a fetch parameter. I passed a function that modifies the request to fit the requirements to skip the preflight, and it seems to work fine for our purposes. Pasted here in case anyone else encounters the same problem:

function fetchWrapper(req, opt) {
  const auth = opt.headers['Authorization']
  delete opt.headers['Authorization']
  const api = opt.headers['Dropbox-API-Arg']
  delete opt.headers['Dropbox-API-Arg']
  if (opt.headers['Content-Type'])
    opt.headers['Content-Type'] = 'text/plain; charset=dropbox-cors-hack'
  const url = new URL(req)
  if (api)
    url.searchParams.set('arg', api)
  if (auth)
    url.searchParams.set('authorization',  auth)
  return fetch(url, opt)
}

Of course, I can imagine this may stop working with a future version of the SDK, so use with caution.

aryehsanders avatar Sep 06 '22 12:09 aryehsanders