title: “the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded” from superagent in Android React Native
body: <p>I'm using <code>superagent</code> to upload files from my React Native app. It works perfectly fine on iOS, but on Android it gives this error:</p>
  
  <blockquote>
    <p>Possible causes: the network is offline, Origin is not allowed by
    Access-Control-Allow-Origin, the page is being unloaded, etc.</p>
  </blockquote>
  
  <p>I've created a minimal example here <a href="https://snack.expo.io/@twohill/upload-example" rel="nofollow noreferrer">https://snack.expo.io/@twohill/upload-example</a> and copied the code below in case the snack goes away:</p>
  
  <pre class="lang-js prettyprint-override"><code>import React, { Component } from 'react';
  import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
  import Constants from 'expo-constants';
  import * as DocumentPicker from 'expo-document-picker';
  import superagent from 'superagent';
  
  import AssetExample from './components/AssetExample';
  import { Card } from 'react-native-paper';
  
  const upload = (file, setMessage) =&gt; {
    const { name } = file;
  
    superagent.post('https://example.org/uploads') // &lt;-- change this URL to your server that accepts uploads and is CORS enabled
      .set('Authorization', 'BEARER xxxyyy') // &lt;-- JWT token here
      .attach('uri', file, name)
      .then(
        result =&gt; setMessage(JSON.stringify({result})),
        error =&gt; setMessage(JSON.stringify({error}))
        );
  };
  
  const pickDocuments = async (setMessage) =&gt; {
    const file = await DocumentPicker.getDocumentAsync({ copyToCacheDirectory: true });
    if (file.type === "success") {
      upload(file, setMessage);
    }
  }
  
  export default class App extends Component {
    state = {
      message: null,
    }
    render() {
      const { message } = this.state;
      return (
  
        &lt;View style={styles.container}&gt;
         &lt;TouchableOpacity onPress={() =&gt; pickDocuments(message =&gt; this.setState({message}))}&gt;
          &lt;Text style={styles.paragraph}&gt;
            Tap to upload a file
          &lt;/Text&gt;
          &lt;Card&gt;
            &lt;AssetExample /&gt;
          &lt;/Card&gt;
          &lt;Card&gt;&lt;Text&gt;{message}&lt;/Text&gt;&lt;/Card&gt;
           &lt;/TouchableOpacity&gt;
        &lt;/View&gt;
      );
    }
  }
  
  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      paddingTop: Constants.statusBarHeight,
      backgroundColor: '#ecf0f1',
      padding: 8,
    },
    paragraph: {
      margin: 24,
      fontSize: 18,
      fontWeight: 'bold',
      textAlign: 'center',
    },
  });
  
  </code></pre>
  
  <p>If I console.log the error it gives the following:</p>
  
  <pre class="lang-none prettyprint-override"><code>Request has been terminated
  Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.
  * http://192.168.1.3:19001/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&amp;dev=true&amp;minify=false&amp;hot=false:282311:24 in crossDomainError
  - node_modules\@sentry\utils\dist\instrument.js:224:24 in &lt;anonymous&gt;
  - node_modules\event-target-shim\dist\event-target-shim.js:818:39 in EventTarget.prototype.dispatchEvent
  - node_modules\react-native\Libraries\Network\XMLHttpRequest.js:566:23 in setReadyState
  - node_modules\react-native\Libraries\Network\XMLHttpRequest.js:388:25 in __didCompleteResponse
  - node_modules\react-native\Libraries\vendor\emitter\EventEmitter.js:190:12 in emit
  - node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:436:47 in __callFunction
  - node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:111:26 in __guard$argument_0
  - node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:384:10 in __guard
  - node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:110:17 in __guard$argument_0
  * [native code]:null in callFunctionReturnFlushedQueue
  </code></pre>
  
  <p>As far as I can tell, on Android the app never tries an upload.
  My server runs <code>express</code> and has the <code>cors</code> middleware enabled with the default configuration</p>
  
  <pre><code>{
    "origin": "*",
    "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
    "preflightContinue": false,
    "optionsSuccessStatus": 204
  }
  </code></pre>
  
  <p>Any ideas what to do here? I get the feeling that the Android is baulking at the "*" origin, but have no idea what to put in place for a mobile app.</p>
  
  <p>Or am I barking up the wrong tree completely?</p>