Rxjs: RxJS Observable.ajax cross domain issue

Created on 25 May 2016  Â·  7Comments  Â·  Source: ReactiveX/rxjs

RxJS version:
5.0.0-beta.8

Code to reproduce:
Codepen example

const { Observable } = Rx;

/*
XMLHttpRequest cannot load https://www.reddit.com/r/reactjs.json.
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://s.codepen.io' is therefore not allowed access.
*/
Observable.ajax(`https://www.reddit.com/r/reactjs.json`)
  .catch(err => console.log('Observable.ajax error', err))
  .subscribe(res => console.log('Observable.ajax', res))

// Same error
Observable.ajax({ url:`https://www.reddit.com/r/reactjs.json`, crossDomain: true })
  .catch(err => console.log('Observable.ajax error', err))
  .subscribe(res => console.log('Observable.ajax', res))

// Success!
Observable.from(fetch(`https://www.reddit.com/r/reactjs.json`))
  .subscribe(res => console.log('window.fetch', res))

Expected behavior:
Unable to request third party APIs using Observable.ajax(...), although using window.fetch with Observable.from works as expected

Actual behavior:
Determine if this is a bug with RxJS's Observable.ajax, or just a configuration issue.

Additional information:

Most helpful comment

As error message mentions, seems like default factory of XHR in ajaxObservable sets withCredentials to true by default (https://github.com/ReactiveX/rxjs/blob/ceb99904c6b56a5d2e832fdd9e07dcf58cb2ad3d/src/observable/dom/AjaxObservable.ts#L28-L29) causes this issue.

A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true.

as an immediate workaround, can provide custom factory to XHR such as

Observable.ajax({ 
    url:`https://www.reddit.com/r/reactjs.json`, 
    crossDomain: true, 
    createXHR: function () {
      return new XMLHttpRequest();
    }
})

allows bypassing default configurations.

I'm not sure if this is expected behavior to set credential by default, or at least need to allow user level configurations to those flags - CC'ing @trxcllnt for asking helps as original author.

All 7 comments

As error message mentions, seems like default factory of XHR in ajaxObservable sets withCredentials to true by default (https://github.com/ReactiveX/rxjs/blob/ceb99904c6b56a5d2e832fdd9e07dcf58cb2ad3d/src/observable/dom/AjaxObservable.ts#L28-L29) causes this issue.

A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true.

as an immediate workaround, can provide custom factory to XHR such as

Observable.ajax({ 
    url:`https://www.reddit.com/r/reactjs.json`, 
    crossDomain: true, 
    createXHR: function () {
      return new XMLHttpRequest();
    }
})

allows bypassing default configurations.

I'm not sure if this is expected behavior to set credential by default, or at least need to allow user level configurations to those flags - CC'ing @trxcllnt for asking helps as original author.

thanks @kwonoj, this works. I'm interested in what @trxcllnt has to say about the defaults as well

@kwonoj @techniq while I helped with an initial port of the ajax method from RxJS-DOM, I believe @blesh is responsible for the version that actually made it into the library. It seems we should be doing something similar to the fix for RxJS-DOM#95, and switch how we create the XHR based on the crossDomain flag.

Let me try to update implementations.

This is not fixed:

There is still an error the above example, when using rxjs 5+ and redux-observable.

const fetchTestReportsEpic = (actions) => {

    const requestSettings = {
        url:'http://localhost:3001/testReports', 
        crossDomain: true,
        body: {},
        responseType:'json',
    }

    return actions.ofType(ActionTypes.FETCH_TEST_REPORTS)
        .switchMap(() => 
            Observable.ajax(requestSettings)
            .map(payload => { 
                console.log(payload);
                fetchTestReportsFulfilledAction(payload) 
            }));
}

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3001/testReports. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Even adding the headers fails to work. There is no clear solution for this, and the examples from the rdxjs documentation also have the same issue.

Hi guys,
I too face the same issue. There was an example using:
import {ajax} from "rxjs/observable/dom/ajax";
And just calling whatever ajax.getJSON("http://...") will result in an error that Access-Control-Allow-Origin header is missing.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dooreelko picture dooreelko  Â·  3Comments

cartant picture cartant  Â·  3Comments

benlesh picture benlesh  Â·  3Comments

Zzzen picture Zzzen  Â·  3Comments

jakovljevic-mladen picture jakovljevic-mladen  Â·  3Comments