Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RxJS Observable.ajax cross domain issue #1732

Closed
techniq opened this issue May 25, 2016 · 7 comments · Fixed by #1758
Closed

RxJS Observable.ajax cross domain issue #1732

techniq opened this issue May 25, 2016 · 7 comments · Fixed by #1758
Assignees

Comments

@techniq
Copy link

techniq commented May 25, 2016

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:

@kwonoj
Copy link
Member

kwonoj commented May 30, 2016

As error message mentions, seems like default factory of XHR in ajaxObservable sets withCredentials to true by default (

if ('withCredentials' in xhr) {
xhr.withCredentials = true;
) 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.

@techniq
Copy link
Author

techniq commented May 31, 2016

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

@trxcllnt
Copy link
Member

@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.

@kwonoj
Copy link
Member

kwonoj commented Jun 8, 2016

Let me try to update implementations.

kwonoj added a commit to kwonoj/rxjs that referenced this issue Jun 9, 2016
- AjaxRequest now support setting withCredentials flag

closes ReactiveX#1732, ReactiveX#1711
kwonoj added a commit to kwonoj/rxjs that referenced this issue Jun 9, 2016
- AjaxRequest now support setting withCredentials flag

closes ReactiveX#1732, ReactiveX#1711
kwonoj added a commit to kwonoj/rxjs that referenced this issue Jun 13, 2016
- AjaxRequest now support setting withCredentials flag

closes ReactiveX#1732, ReactiveX#1711
@stiofand
Copy link

stiofand commented Nov 27, 2017

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.

@ghost
Copy link

ghost commented Feb 8, 2018

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.

@lock
Copy link

lock bot commented Jun 6, 2018

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.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants