I want to check if my site is running under HTTPS from within my template so that I can conditionally add S's to the HTTPs of my external javascript libraries (namely, jQuery). How can I do that?
If your resources are hosted on the same machine as you are serving requests from, it may not need to specify a url scheme at all:
<script src="/static/js/myfile.js" type="text/javascript"></script>
This will use the same protocol (http or https) and server as the request to the original page.
Edit 2 (2016):
If you're accessing a resource on another server, the best solution now (as pointed out by mpen below) is to use the relative URL scheme:
<script src="//media.example.com/static/js/myfile.js" type="text/javascript"></script>
This will automatically connect to the server using http or https depending on the connection to the current page.
Note that this may cause some problems if you need to support old browsers.
Edit: Alternatively, if you really need the info in your template for some reason, you can add the request context processor, and use a RequestContext in your views. This places a request variable in your template context, which gives you access to the HttpRequest object. You can then test if the request is secure by checking the value of request.is_secure
For example:
<script src="http{% if request.is_secure %}s{% endif %}://media.example.com/static/js/myfile.js" type="text/javascript"></script>
I'm not sure if Google did this at the time I asked this question, but they now recommend you add the library via
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
The // will use whatever scheme you are currently using -- no extra code or conditionals required.
Check the request in the View with is_secure(), and send it to the template.
Please consider using the {% static %} template tag (in Django >= 1.4) which can be configured to host media files on a separate domain or server. This will do away with your is_secure problem.
https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:templatetag-staticfiles-static
for checking the connection scheme, you can use the request.scheme attribute
{% if request.scheme == "http" %}
{% elif request.scheme == "https" %}
{% endif %}
Related
Im trying to dynamically change the link of a button based on which div a user has currently selected.
I tried to run a quick test with a JS variable in the HTML script tag, but Django isn't reading the variable like a num.
<script type="text/javascript">
const testing = 10
</script>
<a href="{% url 'battlefield:onevsone_trainer_selection' num_trainers=testing %}" class='description__button btn btn__large'>Next ></a>
URL looks like:
path('one-vs-one/trainers/<int:num_trainers>', views.oneVsOne, name='onevsone_trainer_selection')
Not sure exactly why it's not working. When I passed it a string of '10' it worked
Django templates are handled server side by django, which means by the time the client browser has received the HTML, the url function, i.e. {% url 'battlefield:onevsone_trainer_selection' num_trainers=testing %}, will have been processed. Javascript, of course, runs in the browser, and you can't pass a javascript variable to a django function after it has arrived at the client.
If you want to change this clientside (without communicating with the server via ajax or something) you might need to change the href attribute directly. You could do something like:
<a id='changeableUrl' href="{% url 'battlefield:onevsone_trainer_selection' num_trainers=1 %}" class='description__button btn btn__large'>Next ></a>
<script>
//figure out where the URL should be going
const testing = 10
//get the current URL
url = document.getElementById('changeableUrl').getAttribute("href")
///replace the end of the url href with our value
url.replace('/1/', '/'+testing+'/')
///write back to the link attribute
document.getElementById('changeableUrl').setAttribute("href", url)
</script>
What you should understand is that django template engine works server-side, whereas Javascript only does its job on client side.
What happens is that you are asking django to render the following template :
<script type="text/javascript">
const testing = 10
</script>
<a href="one-vs-one/trainers/testing" class='description__button btn btn__large'>Next ></a>
Here, testing is not a javascript variable, it's just plain html content. Moreover, it's not an integer at rendering time, so the regex used internally by django shall not be matched and a rendering error shall be raised.
If you really want to set the url paramater client-side, then I see two solutions :
The first is to build the url manually without using the django url function. :
<a href="" id="to-change" class='description__button btn btn__large'>Next ></a>
<script type="text/javascript">
document.getElementById("to-change").href = "one-vs-one/trainers/" + num_trainer;
</script>
The second solution is the one proposed by SamSparx.
Whatever the solution you choose, you should carefully keep in mind that neither of the two if fully safe. In the first case, you make the code a little bit less maintainable by giving more work if one day you change the url in your urls.py file. In the second one, you expose you to a url that is predefined. If JS is not enabled or if something wrong happens on the browser of your client, it may mean that your link shall be linked to what it should not.
I manage a Django project collaborating with different front end programmers. Sometimes in my html template I have
<script src="https://example.com/script.js"></script>
Is there a way that I in my settings.py define whitelisting external domains that can be called. In this example, if example.com is not whitelisted, calling to that domain should be prevented.
you could do it like this:
settings.py
ALLOWED_JS = ['example.com', 'example2.com']
template
{% for domain in ALLOWED_JS %}
<script src="https://{{domain}}/script.js"></script>
{% endfor %}
Good day,
So I have made a mobile Android/IOS app that communicates with django backend through the http requests. As you understand the backend is hosted on some https://www.example.com domain...
However, in case a user accesses that domain or any extensions (/home, /profile and etc..) from any web browser from any platform, I want to display just a plain page (maybe the name of the app). How can I do so?
Thanks
If you don't want to add new middleware you can add this in your base.html template. Other way would be to write separate middleware in which you check user_agent and redirect to specific page containing your app name
{% if request.user_agent.is_mobile %}
NAME OF YOUR APP
{% else %}
Normal page
{% endif %}
This question is very similar to one I just asked href: Can I get Google search results to use/display the final redirect url?, but now the question is specific to Django.
My site has webpage urls that use the following format:
www.mysite.com/id/pretty_title
The front page links to these pages, but the href actually contains some parameters:
www.mysite.com/id/?some_ugly_parameters_to_let_me_know_what_search_it_is_from
This then redirects to
www.mysite.com/id/pretty_title
which shows the page.
My issue is that Google's search results show the link to the page as the ugly url instead of the pretty redirected one.
What I have learned is that I need to provide a canonical link. But how can I do this when the ugly url page never really exists, at least not as one that I have written?
What happens server side is that the view of the ugly url does a redirect:
return HttpResponseRedirect(pretty_url)
I think this is the correct built template tag that you're looking for.
{{ request.build_absolute_uri }}
You can just put it as part of the HTML returned from the Django template, in the <head> section.
Do you have a base.html in your Django? You can setup a {% block %} as a placeholder for the canonical URL and then set that value in each individual page that {% extends base.html %}
base.html
<html>
<head>
<link rel="canonical" href="{% block canonical_url %}{% endblock %}">
</head>
...
A lot of these proposed solutions have issues if (1) you want your www subdomain to be the canonical one and (2) there are URL params in the request path.
I would actually propose to hard code it in the base template and append request.path.
<link rel="canonical" href="https://www.example.com{{ request.path }}">
If you do end up wanting to use build_absolute_uri, I would do it as follows in your view (or you could create a template function):
canonical_url = request.build_absolute_uri(request.path)
Calling build_absolute_uri() without an argument will call request.get_full_path() and append that to your domain. If a user finds your site via https://www.example.com/?param=123, your canonical URL will include that param.
Right now, if I want to check whether the current page is accessed through http:// or https://, I will use the following Javascript in my templates and write html from document.write:
<script type="text/javascript">
var protocol = document.location.protocol;
if (protocol == "http:")
document.write("regular");
else
document.write("secured");
</script>
Is there another way to achieve the above in Django's template without using Javascript?
if you use a RequestContext, you can do the following:
<p>You used: {% if request.is_secure %}HTTPS{% else %}HTTP{% endif %}
See the relevant part of the Django documentation.
Since Django 1.10, you can use:
request.scheme
in a view, or in a template:
{{ request.scheme }}
From the docs
A string representing the scheme of the request (http or https usually).
You need to enable the appropriate request context processor in your setting.py file:
TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.request',)
The template will now have a variable named request that contains the current HttpRequest. You can use it to find the protocol:
{{ request.is_secure }}
Try using RequestContext and request.is_secure in your template.
One caveat, the process of detecting HTTPS can differ from one server setup to the next so you may have to do a little work to get request.is_secure working. You can get it working either by ensuring that your front end / reverse proxy sets 'HTTP_X_FORWARDED_HOST' or by writing a middleware class that is custom to your setup.
Use the deprecated SetRemoteAddrFromForwardedFor code as a starting point, if you go the custom middleware route.