I have written a Django script that runs a Python parser to web s*e. I am sending the request to the Django script via AJAX. However, when the Ajax runs, it comes back as 404 not found for the URL. Why is this happening?
My code is below:
Ajax (with jQuery):
//send a `post` request up to AWS, and then
//insert the data into the paths
$.post('/ca', function(data){
//evaluate the JSON
data = eval ("(" + data + ")");
//insert the vars into the DOM
var contentOne;
contentOne = data.bridge_time;
contentOne += 'min delay';
$('#timeone').html(contentOne);
var contentTwo;
contentTwo = data.tunnel_time;
contentTwo += 'min delay';
$('#timetwo').html(contentTwo);
//if this falls through, push an error.
var tunnel_time = data.tunnel_time;
var bridge_time = data.bridge_time;
var tunnel = document.getElementById('tunnel');
var bridge = document.getElementById('bridge');
var tunnelText = document.getElementById('timeone');
var bridgeText = document.getElementById('timetwo');
//algo for the changing icons. Kudos to Vito
if(tunnel_time<bridge_time){
tunnel.src="tunnel3.png";
bridge.src="bridge2r.png";
}else if( bridge_time<tunnel_time){
bridge.src="bridge21.png";
tunnel.src="tunnel2r.png";
}else{
bridge.src="bridge2n.png";
tunnel.src="tunnel2g.png";
}
$.fail(function() {
alert("We're sorry. We are having an error. Check back later.");
});
});
My urls.py:
from django.conf.urls.defaults import *
from views import views
urlpatterns = patterns('',
(r'^/us', views.american_time),
(r'^/ca', views.canadian_time),
)
My urls.py and my views.py are in the same folder, if that makes any difference. They are just titled views.py and urls.py. Thank you!
Try
from django.conf.urls.defaults import *
from views import views
urlpatterns = patterns('',
(r'^/us/$', views.american_time),
(r'^/ca/$', views.canadian_time),
)
Also you have to add the trailing slash in your JavaScript.
I just resolved this: there was an error in my urls.py. My system was having trouble with the .defaults that is was supposed to import from. Also, I didn't have a Django project set up, so It wouldn't import the views.
Related
I'm currently coding a Flask application with a simplified version of my code below.
#app.py
from flask import Flask, render_template, request
# Configure application"'
app = Flask(__name__)
# Ensure templates are auto-reloaded
app.config\["TEMPLATES_AUTO_RELOAD"\] = True
#app.route("/")
def index():
return render_template("gettranslation.html")
#app.route("/translate")
def translate():
word = request.args.get("word")
lang = request.args.get("lang")
return render_template("translate.html", lang = lang, word=word)
The default webpage should log a translation of the given words, but instead it just logs the word before translation, though when visited the webpage being fetched takes a second to load and then shows the correct translation. How do I fetch this correct translation?
Here is simplified code from my two files:
<!--translate.html-->
<script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<div id="google_translate_element"></div>
<p id="to-translate">{{word}}</p>
<script>
var lang = "{{ lang }}";
var lang = lang[0] + lang[1];
console.log(lang);
function googleTranslateElementInit() {
new google.translate.TranslateElement(
{
pageLanguage: lang
},
"google_translate_element"
);
}
window.href = window.href + "/#googtrans(" + lang + "|en)";
</script>
<!--gettranslation.html-->
<script>
async function translate(sourcelang, destlang, word){
var url = '/translate?word=' + word + "&lang=" + sourcelang + "/#googtrans(" + sourcelang + "|" + destlang + ")";
console.log(url);
let response = await fetch(url, {redirect: 'follow'});
let text = await response.text();
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(text, 'text/html');
var translation = htmlDoc.getElementsByTagName('p')[0].innerHTML;
console.log(translation);
}
translate("fr", "en", "bonjour");
</script>
I thought using await or redirect: follow would work but neither did. I also got the idea to use #googletrans("source|dest") from this question: Trigger Google Web Translate Element if that's helpful.
Someone there saidthe Google translate select box is created after the window.load event triggers, so that is could be what is messing up my fetch request but if so I have no idea how to fix that.
Thanks in advance!
The html template is rendered at server side, this might be causing the problem with your script.
Why don't you translate the words in flask and then send them to the template? There are libraries for that such as Flask-Googletrans Flask-Googletrans.
You can translate in the view function:
from flask_googletrans import translator
ts = translator(app)
in the jinja template
<h1>{{ translate(text='your text', src='en', dest=['fr']) }}</h1>
I hope this helps
Hello guys I have search and I didnt find anything, do you know how to get a laravel route name on js?
For example on php we can do $name = Route::currentRouteName();
In your layout.blade.php
<body data-page="{{ Route::currentRouteName() }}">
#yield('content')
<script>
var currentRouteName = document.body.dataset.page;
</script>
</body>
If you for some reason don't like injecting stuff in your DOM just to read it with JavaScript, you can do something else:
routes/web.php
Route::get('your-route', function() {
return response()
->view('your-view', compact('your-data'))
->header('route-name', 'your-route');
})->name('your-route');
your-view.blade.php
var req = fetch(document.location, {
'method': 'OPTIONS'
}).then((res) => alert(res.headers.get('route-name')));
Take a look at Ziggy, this npm package helps to integrate Laravel named routes with your frontend, with it you can easely get current route name and even acces routes for all your application endpoint just like you would do with Laravel:
https://github.com/tighten/ziggy
Examples From the Documentation:
//app.js
//get current route name
// Route called 'events.index', with URI '/events'
// Current window URL is https://ziggy.test/events
route().current(); // 'events.index'
// routes/web.php
Route::get('posts/{post}', fn (Request $request, Post $post) => /* ... */)->name('posts.show');
// app.js
route('posts.show', 1); // 'https://ziggy.test/de/posts/1'
I'm trying to create a file in the File Cabinet and write to it in a Client Script. Checking the API reference, I see that all the File objects are Server-side only.
Does that mean you can't create and write to a file in a Client script? I tried to use the code in my Client script anyway, but got the error:
Fail to evaluate script: {"type":"error.SuiteScriptModuleLoaderError","name":"{stack=[Ljava.lang.Object;#59c89ae9, toJSON=org.mozilla.javascript.InterpretedFunction#5a4dd71f, name=MODULE_DOES_NOT_EXIST, toString=org.mozilla.javascript.InterpretedFunction#1818dc3c, id=, message=Module does not exist: N/file.js, TYPE=error.SuiteScriptModuleLoaderError}","message":"","stack":[]}
When I tried to save it in NetSuite as the script file. Does the above mean that the N/File object can't be loaded in a Client script?
Can I write to a file in a Client script?
Create a Client Script - this Script will contain the function to call the Suitelet and pass along information from the current record/session if needed.
function pageInit{
//required but can be empty
}
function CallforSuitelet(){
var record = currentRecord.get();
var recId = record.id;
var recType = record.type
var suiteletURL = url.resolveScript({
scriptId:'customscriptcase3783737_suitelet',// script ID of your Suitelet
deploymentId: 'customdeploycase3783737_suitelet_dep',//deployment ID of your Suitelet
params: {
'recId':recId,
'recType':recType
}
});
document.location=suiteletURL;
}
return {
CallforSuitelet : CallforSuitelet,
pageInit : pageInit
}
Create a Suitelet - this script will create the file
function onRequest(context) {
var requestparam = context.request.parameters;
var recId = requestparam.recId; //the same name of the fields specified in url.resolveScript parameters from Client Script
var recType = requestparam.recType;
var objRecord = record.load({
type: record.Type.___,//insert record type
id: recId
});
var content = 'Insert Content Here';
var xml = "<?xml version=\"1.0\"?>\n<!DOCTYPE pdf PUBLIC \"-//big.faceless.org//report\" \"report-1.1.dtd\">\n";
xml += "<pdf>\n<body font-size=\"12\">\n<h3>Sample PDF</h3>\n";
xml += "<p></p>";
xml += content;
xml += "</body>\n</pdf>";
context.response.renderPdf({xmlString: xml});
}
return {
onRequest: onRequest
}
As you've already discovered, server-only modules can't be called from client-side scripts directly, but this can be done via a Suitelet. You will need to decide how the Suitelet does it's work. An example of the principal at work can be found here and here
I'm attempting to use scrapy and splash to retrieve the Staff, job titles, and emails from a particular website's staff page. https://www.kennedaleisd.net/Page/3884. I'm using splash with docker since the emails are hidden behind dynamic javascript code.
The spider works on the first page of the staff however I can't seem to get it to work on the 2nd or 3rd pages. I opened up developer tools and have copied the request that is sent when you click on one of the pagination links and then attempted to replicate that request in the spider. The problem I appear to be having is that the response for that request only returns a sub-set of the code for the entire page (Just the staff for that page) instead of everything like the accompanying javascript. So when that is passed onto splash it doesn't have the necessary script to create the dynamic code. I also noticed that the request appeared to have a cookie entry of RedirectTo which goes back to the parent page. I had attempted including that cookie in the requests or passing cookies from the first request to the paginated pages, but it didn't seem to be working. I also attempted some lua scripts in the splash request but that didn't seem to be getting me what I wanted either. Below I've included the spider as I have it right now.
I'm not sure if there's some way to re-use the javascript with subsequent requests or to user that redict cookie in some way to get the rest of the needed code. Any help would be appreciated. I realize the pagination is probably not the proper way to loop through pages but I figured I could work on that once I get the reading of the data figured out.
import scrapy
from scrapy_splash import SplashRequest
class TestSpider(scrapy.Spider):
name = 'TestSpider'
start_urls = ['https://www.kennedaleisd.net/Page/3884']
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url, self.parse, meta={
'splash': {
'endpoint': 'render.html',
'args': {'wait': 0.5}
}
})
def parse(self, response):
for item in response.css('div.staff'):
name = item.css('li.staffname::text').get()
title = item.css('li.staffjob::attr(data-value)').get()
email = item.css('li.staffemail a::attr(href)').get()
staffURL = response.request.url
yield {
'name': name,
'title': title,
'email': email,
'staffURL': staffURL
}
if response.css('a.ui-page-number-current-span::text').get() == '1':
pagination_results = response.css(
'li.ui-page-number a:not([class^="ui-page-number-current-span"])::text').getall()
base_url = 'https://www.kennedaleisd.net//cms/UserControls/ModuleView/ModuleViewRendererWrapper.aspx?DomainID=2042&PageID=3884&ModuleInstanceID=6755&PageModuleInstanceID=7911&Tag=&PageNumber='
# backend_url = '&RenderLoc=0&FromRenderLoc=0&IsMoreExpandedView=false&EnableQuirksMode=0&Filter=&ScreenWidth=922&ViewID=00000000-0000-0000-0000-000000000000&_=1584114139549'
for i in pagination_results:
next_page = base_url + str(i) # + backend_url
yield response.follow(next_page, callback=self.parse, meta={
'splash': {
'endpoint': 'render.html',
'args': {'wait': 3}
}
})
Well, after a bit of tinkering I figured out how to handle this with the lua script I had been toying with. I'd still much prefer a different method if there is something that is a bit more official rather than using scripting.
import scrapy
from scrapy_splash import SplashRequest
script_frontend = """
function main(splash)
splash:init_cookies(splash.args.cookies)
assert(splash:go{
splash.args.url,
headers=splash.args.headers,
http_method=splash.args.http_method,
body=splash.args.body,
})
assert(splash:wait(3))
assert(splash:select('#ui-paging-container > ul > li:nth-child("""
script_backend = """) > a'):mouse_click())
assert(splash:wait(3))
local entries = splash:history()
local last_response = entries[#entries].response
return {
url = splash:url(),
headers = last_response.headers,
http_status = last_response.status,
cookies = splash:get_cookies(),
html = splash:html(),
}
end
"""
class TestSpider(scrapy.Spider):
name = 'TestSpider'
start_urls = ['https://www.kennedaleisd.net/Page/3884']
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url, self.parse, meta={
'splash': {
'endpoint': 'render.html',
'args': {'wait': 0.5}
}
})
def parse(self, response):
for item in response.css('div.staff'):
name = item.css('li.staffname::text').get()
title = item.css('li.staffjob::attr(data-value)').get()
email = item.css('li.staffemail a::attr(href)').get()
staffURL = response.request.url
yield {
'name': name,
'title': title,
'email': email,
'staffURL': staffURL
}
if response.css('a.ui-page-number-current-span::text').get() == '1':
pagination_results = response.css(
'li.ui-page-number a:not([class^="ui-page-number-current-span"])::text').getall()
for i in pagination_results:
script = script_frontend + str(i) + script_backend
yield SplashRequest(self.start_urls[0], self.parse,
endpoint='execute',
cache_args=['lua_source'],
args={'lua_source': script},
headers={'X-My-Header': 'value'},
session_id='foo'
)
I'm trying to use flask with url_for. The problem is that when I try to launch an alert with the value of the javascript variable everything seems ok, but when I try to launch a alert with the url_for the content of the variable is not printed. What I'm doing wrong? or What is missing in my code?
How can I pass a JavaScript variable into the url_for function?
html code:
<a class="dissable_user_btn" data-user_id="{{user.id}}" href="#" title="Change Status"><i class="fa fa-plug"></i>
</a>
JS Code:
<script type="text/javascript">
$(document).ready(function(){
$('.dissable_user_btn').click(function( event ) {
var user_id = $(this).data("user_id")
alert(user_id) //everything ok
alert ('{{url_for('.dissable', _id=user_id)}}'); //dont print the valur of user_id
</script>
Short answer: you can't. Flask & Jinja2 render the template on the server side (e.g. Flask is translating all of the {{ }} stuff before it sends the HTML to the web browser).
For a URL like this where you're including a variable as part of the path you'd need to build this manually in javascript. If this is an XHR endpoint I'd recommend using GET/POST to transfer the values to the server as a better best practice than constructing the URL this way. This way you can use Jinja:
$(document).ready(function(){
var baseUrl = "{{ url_for('disable') }}";
$('.dissable_user_btn').click(function(event) {
var user_id = $(this).data("user_id");
// first part = url to send data
// second part = info to send as query string (url?user=user_id)
// third parameter = function to handle response from server
$.getJSON(baseUrl, {user: user_id}, function(response) {
console.log(response);
});
});
});
I found another solution for this. My problem started when I needed to pass a variable with space.
First I created a function to remove trailing and leading spaces
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');}
After that, I used the function and encoded the URL
<script type="text/javascript">
$(document).ready(function(){
$('.dissable_user_btn').click(function( event ) {
var user_id = $(this).data("user_id")
alert(user_id)
user_id = strip(user_id).replace(" ","%20");
alert ('{{url_for('.dissable', _id='user_id')}}.replace('user_id',user_id);
</script>
It worked pretty nice for me!
This is how I applied to my problem
<script>
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');}
$(document).ready(function() {
$('#exportcountry').click(function() {
var elemento = document.getElementById("countryexportbtn");
var country = strip(elemento.textContent).replace(" ","%20");
$('#exportevent').load("{{ url_for('get_events',country = 'pais') }}".replace('pais',country));
});
});
</script>