I made an Angular application able use an online api to get a json and do stuff.
But, although the json is the same, if I try to change only the url of the json by setting a local url of a server written in django, angular would seem not to connect anymore ...
My question is, why if with an online cloud server works, with a local one wouldn't?
I tried making this server "on cloud" opening the router's port, also setting up a ddns, and using postman or a browser it seems to work, but when i try to connect with angular it still doesn't get the data...
I am sure 100% that the server answer, with the right json data, because django prints on console that he received a HTTP GET request :
http://i.imgur.com/TIQnIcR.png
I remind you that the HTTP angular request worked with another api, but i will still show up some code :
export class ProdottoService {
private prodotti: Array<ProdottoModel>;
constructor(private httpClient: HttpClient) {
this.prodotti = new Array<ProdottoModel>();
var url:string = "https://gist.githubusercontent.com/saniyusuf/406b843afdfb9c6a86e25753fe2761f4/raw/523c324c7fcc36efab8224f9ebb7556c09b69a14/Film.JSON";
var local_url:string = "http://127.0.0.1:8000/films/?format=json";
httpClient.get(local_url)
.subscribe((films : Array<Object> ) => {
films.forEach((film => {
this.prodotti.push(new ProdottoModel(film));
}));
}
);
}
getProdotti(): Array<ProdottoModel> {
return this.prodotti;
}
}
Result using external api :
http://i.imgur.com/MT7xD9c.png
Thanks in advace for any help :3
-- EDIT -- IS A CORS ISSUE
In django settings.py file :
CORS_ORIGIN_WHITELIST = (
'localhost:8000',
'127.0.0.1:4200'
)
INSTALLED_APPS = (
...
'corsheaders',
...
)
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
But i don't know if there's a way to set-up CORS settings in Angular
Based on feedback, this is a CORS issue. Your Django server is getting the requests and responding because localhost is an implicitly trusted domain in Django's dev environment, but it isn't configured properly to set the cross origin header, so the browser is not allowing your app to see the response because the server hasn't authorized the domain explicitly.
The problem here is that you've set CORS white list like this:
CORS_ORIGIN_WHITELIST = ( 'localhost:8000', '127.0.0.1:4200' )
it needs to be like this:
CORS_ORIGIN_WHITELIST = ( 'localhost:4200' )
angular runs on localhost, not 127.0.0.1, even though that's what localhost is an alias for, your browser still differentiates them for CORS. Also, you do not need to whitelist the domain your serving off of, that's not crossing any origin as it's the same origin.
In your screenshot, it looks like the response is type "document..." something. The simplest fix, with only the code here, is to convert the string to JSON.
JSON.parse(films)
This is the wrong answer, because it's being set to that because of the CORS issue in the other answers.
Related
I run a ReactJS front end application and Django REST back end/API both on the same webhost. The application works perfectly fine on localhost, however when you run it from somewhere else it can't seem to connect to the API.
Console of client's browser:
Django REST running on the server:
Am I supposed to connect to it using the external IP of the server instead of localhost? Localhost should work right, since both the frontend and Django API are hosted on the same server?
before fetch the django rest_api, make sure you setup django-cors-headers in your backend settings.py. for more information take a look at this link.
pip install django-cors-headers
settings.py :
INSTALLED_APPS = [
...
'corsheaders',
...
]
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'corsheaders.middleware.CorsPostCsrfMiddleware',
...
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
In case someone is looking for an answer, I've learned a few things since posting:
The Django API has to be accessed by the IP, not localhost.
Since my website is on HTTPS, Django has to be accessed by HTTPS as well or it won't work.
Since Django runserver doesn't support HTTPS you need to host it with a webserver (you should do this anyway in production), I used Apache for this.
Thanks to xxnora for giving me tips and steering me in the right direction.
I have a django api (djangorestframekwork, django2.1, python 3.6) that I run locally - http://127.0.0.1:8000/api/cards/b361d7e2-6873-4890-8f87-702d9c89c5ad. This api seems to work well. I can hit it via the web api or use curl/requests to add to or view the database.
Now, I want to be able to have my React project hit this api. I can have my react project hit a different api and it returns the data, but when I replace that URI with my own URI it breaks.
App.js - there is one line commented out. Switch that out with the other to switch between the public and private api.
import React from 'react'
import keyforge from '../api/keyforge'
import localhost from '../api/localhost'
import SearchBar from './SearchBar'
class App extends React.Component {
onSearchSubmit = async (term) => {
const response = await localhost.get("api/cards/" + term)
//const response = await keyforge.get("api/decks/" + term)
console.log(response)
}
render () {
return (<div className='ui container'>
<SearchBar onSubmit={this.onSearchSubmit} />
</div>)
}
}
export default App
keyforge.js - this one works!
import axios from 'axios'
const proxyurl = 'https://cors-anywhere.herokuapp.com/'
const url = 'https://www.keyforgegame.com/'
export default axios.create({
// baseURL: 'https://www.keyforgegame.com/api/decks/'
baseURL: proxyurl + url
})
localhost.js - this one does not work
import axios from 'axios'
const proxyurl = 'https://cors-anywhere.herokuapp.com/'
const url = 'http://127.0.0.1:8000/'
export default axios.create({
baseURL: proxyurl + url
})
Error message:
GET https://cors-anywhere.herokuapp.com/http://127.0.0.1:8000/api/cards/b361d7e2-6873-4890-8f87-702d9c89c5ad 404 (Not Found)
Uncaught (in promise) Error: Request failed with status code 404
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:78)
On my computer - http://127.0.0.1:8000/api/cards/b361d7e2-6873-4890-8f87-702d9c89c5ad takes me to the Django api page for that specifc element. If I get rid of the cors-anywhere url I get this error -
Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/cards/b361d7e2-6873-4890-8f87-702d9c89c5ad' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have this cors-anywhere url prepended to it to solve the No Access-Control-Allow-Origin error that you see when I hit this to the public api. Since I get the same error when I hit my own private api, I am using the same solution (e.g. the cors-anywhere url prepeneded to my url.
Thoughts?
Probably because you didn't enabled CORS on your django rest project. There is a tool called django-cors-headers, Install it via pip install django-cors-headers, add it's midlleware and enable it in your settings.py file.
pip install django-cors-headers
then add it to installed apps:
INSTALLED_APPS = (
...
'corsheaders',
...
)
add it's middleware:
MIDDLEWARE_CLASSES = (
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
)
and finally add this variable in the end of your settings.py file:
CORS_ORIGIN_ALLOW_ALL = True
Find out more about it here: django-cors-headers on github
Your keyforge.js file works because you're hitting an already hosted website which has CORS enabled at it's backend as well. You need to add CORS at your Django backend as well. From what you've said, it seems that you've only added it at the front end. Probably something like could help you.
How can I enable CORS on Django REST Framework
I'm building my first app with Ionic and I'm using Django Rest Framework as API.
I just want to create a simple page in Ionic that shows a list of categories.
I've created the model Category, and the ViewSets for the API. When I go to the Django-rest-framwork viewer (http://localhost:3010/category/) everything works fine.
But when I try to get the results (with Ionic) I get this error:
XMLHttpRequest cannot load http://localhost:3010/category/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.
My code:
import {Page, Platform, NavController} from 'ionic/ionic';
import {EmployeeDetailsPage} from '../employee-details/employee-details';
import {Http} from 'angular2/http';
#Page({
templateUrl: 'build/pages/getting-started/getting-started.html'
})
export class GettingStartedPage {
constructor(platform: Platform, nav: NavController, http: Http) {
this.platform = platform;
this.nav = nav;
this.http = http;
this.http.get("http://localhost:3010/category/")
.subscribe(data =>{
this.items=JSON.parse(data._body).results;//Bind data to items object
},error=>{
console.log(error);// Error getting the data
} );
}
}
You need to send CORS headers to Ionic Framework to let cross-domain ajax work, since your ionic app is hosted on port 8100, and django-server is running on port 3010, this is considered a cross-domain request.
For django, install CORS headers app through pip.
In your settings, enable 'corsheaders' app, and also add the allowed urls.
# this disables Cross domain requests
CORS_ORIGIN_ALLOW_ALL = False
# this allows cookie being passed cross domain
CORS_ALLOW_CREDENTIALS = True
# this is the list of allowed origins for cross domain ajax
CORS_ORIGIN_WHITELIST = (
'localhost:8100',
)
You may need to install CORS.
If you are testing on chrome you might also need to allow cross origin (There is an extension for it) which should get you around the CORS issue.
I have just pushed a web app into production and requests to my nodejs no longer contain the user cookie that Django has been setting by default on my localhost (where it was working).
my nodejs looks for the cookie like this
io.configure(function(){
io.set('authorization', function(data, accept){
if (data.headers.cookie) {
data.cookie = cookie_reader.parse(data.headers.cookie);
return accept(null, true);
}
return accept('error',false);
});
io.set('log level',1);
});
and on localhost has been getting this
cookie: 'username="name:1V7yRg:n_Blpzr2HtxmlBOzCipxX9ZlJ9U"; password="root:1V7yRg:Dos81LjpauTABHrN01L1aim-EGA"; csrftoken=UwYBgHUWFIEEKleM8et1GS9FuUPEmgKF; sessionid=6qmyso9qkbxet4isdb6gg9nxmcnw4rp3' },
in the request header.
But in production, the header is the same but except no more cookie. Does Django only set this on localhost? How can I get it working in production?
I've tried setting these in my settings.py
CSRF_COOKIE_DOMAIN = '.example.com'
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = False
But so far no good.
Any insight would be great.
I just figured it out. I was making a request to nodejs on the client like this
Message.socket = io.connect('http://123.456.789.10:5000');
Where I used my respective IP address and port that my nodejs was listening on. This is considered cross domain so browsers won't include cookies in the request. Easy fix by changing it to
Message.socket = io.connect('http://www.mydomain.com:5000');
This is my first post, and I have a problem I could not make it work django OMAB socialauth of three things I just need to google, facebook, and twitter, google works well with open id, but not much twitter and I put in my
settings. py:
TWITTER_CONSUMER_KEY = '00' this is no real
TWITTER_CONSUMER_SECRET = '00' this is no real
FACEBOOK_APP_ID = '' ihave no key
FACEBOOK_API_SECRET = ''
LINKEDIN_CONSUMER_KEY = ''
LINKEDIN_CONSUMER_SECRET = ''
ORKUT_CONSUMER_KEY = ''
ORKUT_CONSUMER_SECRET = ''ihave no key
GOOGLE_OAUTH2_CLIENT_ID = ''
GOOGLE_OAUTH2_CLIENT_SECRET = ''
SOCIAL_AUTH_CREATE_USERS = True
SOCIAL_AUTH_FORCE_RANDOM_USERNAME = False
SOCIAL_AUTH_DEFAULT_USERNAME = 'socialauth_user'
SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete'
LOGIN_ERROR_URL = '/login/error/'
#SOCIAL_AUTH_USER_MODEL = 'app.CustomUser'
SOCIAL_AUTH_ERROR_KEY = 'socialauth_error'
GITHUB_APP_ID = ''
GITHUB_API_SECRET = ''
FOURSQUARE_CONSUMER_KEY = ''
FOURSQUARE_CONSUMER_SECRET = ''
LOGIN_URL = '/login-form/'
LOGIN_REDIRECT_URL = '/'
LOGIN_ERROR_URL = '/login-error/'
I am using the example that comes in the zip of OMAB socialauth django , but not working.
When I created my twitter app, I wrote my domain www.sisvei.com , I am testing locally socialauth django ie 127.0.0.1:8000, then sign in with twitter sends me to this url:
http://127.0.0.1:8000/login/error/ and a message saying is the Incorrect authentication service
this happens with facebook and google oauth and oauth2
I'm new to django and I this much work comprising this part of django socialath hopefully help me, thank you very much.
You need to be more specific on "why it doesn't work". Where are you getting the errors?
When debugging a third-party oauth/openid app in Django, generally it boils down to:
configuration & keys - did you make sure to obtain all of the necessary API keys for the services you will be using, and to add them to your configuration?
urls - did you remember to add the necessary urlpatterns to your base urls.py file?
authentication setup on the server - often, you'll need to have a file available or respond with a specific header when the authentication service hits your server. Have you checked to make sure that is set up?
databases - have you run syncdb after installing the app? Are all the tables set up?
templates - if the third party app requires you to set up templates, do you have them set up?
custom views - are you using custom views? If so, try using the built-in views that came with the third party app first, to see if they work
After those are confirmed, you're going to want to be able to see what requests are taking place. Use the debugger included in Chrome/Safari, or get the web developer add-on for Firefox, and look at the network requests as they happen. Do you see HTTP responses other than 200 (say, 404, 500, 403, etc?) those mean that the services aren't responding correctly.
From your error, it looks like you have not correctly set up your callback URL on Twitter. It should be sending you to www.sisvei.com, not 127.0.0.1. Alternatively, check the URL when you get to the Twitter login page -- is the callback URL in the URL, and is it pointing to 127.0.0.1? Then Django is sending it the wrong callback URL.
Finally this:
I wrote my domain www.sisvei.com python does not support this
Is unclear. As far as I know, Python doesn't care what the domain is.
WAIT A MINUTE ...
Are you using runserver? Are you getting the following error?
Error: "www.sisvei.com" is not a valid port number or address:port pair.
If so, there is an easy fix! Just run it like so:
python manage.py runserver www.sisvei.com:80
That should resolve your error if that's what's happening. You're probably running it as
python manage.py runserver 127.0.0.1
127.0.0.1 is a reserved IP address that points back to localhost, your own computer. As a result, it is not possible to use it for authentication or any other purpose outside of programs running on your own machine. See this article for more info.
I'm not sure, but I might be having similar problems, oscar. For me, SocialAuth was generating an AuthenticationURL for facebook, foursquare and hotmail, but not for google, twitter or any of the other address it supports. I think it may be something wrong with the API, so I posted an issue on the social-auth google group...you may want to check there to see if anyone updates!!
https://code.google.com/p/socialauth/issues/detail?id=282&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary%20Modified