I'm new to Magento2 and trying to figure out how RequireJS works in Magento.
Here is my situation:
I have following module:
app/code/Mymodule/Test/view/frontend/requirejs-config.js
Here is the content of this file:
var config = {
map: {
'*': {
jQuery110: "Mymodule_Test/js/jquery-1.10.2",
jqueryNoConflict: 'Mymodule_Test/js/jquery.no-conflict',
flexslider: 'Mymodule_Test/js/jquery.flexslider-min',
header: 'Mymodule_Test/js/store/header'
}
}
};
My theme is at this location:
app/design/frontend/Mycompany/Basic
My Javascripts are at following location:
app/code/Mymodule/Test/view/frontend/web/js/jquery.no-conflict.js
app/code/Mymodule/Test/view/frontend/web/js/jquery.flexslider-min.js
app/code/Mymodule/Test/view/frontend/web/js/store/header.js
In the PHTML file:
app/code/Mymodule/Test/view/frontend/templates/home.phtml
I added the lines:
require(['jqueryNoConflict', 'flexslider'],function($, flexslider){
(function($) {
$(window).load(function () {
$('.flexslider').flexslider();
});
})(jQuery);
});
When I check my page in browser, I get 404 error with paths:
http://mag2.com.local/pub/static/frontend/Mycompany/Basic/en_US/flexslider.js
But if I change the require[] line to this:
require(['Mymodule_Test/js/jquery.no-conflict', 'Mymodule_Test/js/jquery.flexslider-min'],function($, flexslider){
(function() {
$(window).load(function () {
$('.flexslider').flexslider();
});
})(jQuery);
});
the files are loading.
I also cleared the cache, my theme is correct, I executed the command:
php bin/magento setup:static-content:deploy
So, I am not able to figure out why my requirejs-config.js is not loading. I followed the documentation as well.
I found the problem.
Under pub/static/_requirejs/frontend/Namespace/Theme/en_US, delete the file requirejs-config.js.
Refresh your page and it will be generated again with new content.
This may help someone else with a very similar issue on local with nginx. The /static block was not rewriting correctly and this needed to be added per this comment https://github.com/magento/magento2/issues/7869#issuecomment-268585438
location /static/ {
if ($MAGE_MODE = "production") {
expires max;
}
# Remove signature of the static files that is used to overcome the browser cache
location ~ ^/static/version {
rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
}
location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
add_header Cache-Control "public";
add_header X-Frame-Options "SAMEORIGIN";
expires +1y;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
add_header Cache-Control "no-store";
add_header X-Frame-Options "SAMEORIGIN";
expires off;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
add_header X-Frame-Options "SAMEORIGIN";
}
The detailed explanation is here
As requested by other members, adding the important bits:
Check if you can find the file it's trying to load on the filesystem. If it's there, it would point to a web server configuration problem instead. If it's not check file permission and then do static content deploy.
Related
This is my NGINX conf file:
server {
listen 80;
listen [::]:80;
server_name other.com;
root /home/user/html;
location = / {
}
location / {
return 301 https://mydom.com$request_uri;
}
}
It suppose to redirect every request except main route ("/"). But now it redirect everything with main route too. Where is my mistake?
Your location = / block isolates a single URI - the original request.
By default, Nginx processes any request that ends with a /, by checking if it resolves to a directory, and checking the directory for any files matching those listed in the index directive (default: index.html).
The index directive causes an internal redirection which causes Nginx to repeat the search for a matching location.
You will also need to isolate the redirected request.
For example:
location = / { }
location = /index.html { }
location / { ... }
Alternatively, bypass the index directive and handle it a single location using a try_files statement.
For example:
location = / { try_files /index.html =404; }
location / { ... }
See this document for details.
I have created and tested the POST and GET request methods in Nodejs such that I can send the user through the Gocardless sign-up API perfectly fine.
This is a sign-up form provided by their API which allows them to input their details and then returns the user back after they fill it in.
But when I set up a front-end using Vuejs and make the same calls previously made from the back end using Axios, it seems that because the "redirect_url" fed back to me from the GC API had previously been fed directly into the browser url before, now, because it seems vue-router has control of the browser, I'm getting a cross origin error.
How can I configure the files to have the Nodejs back end acting as if it had control of the browser?
The end points are described here:
https://developer.gocardless.com/api-reference/#core-endpoints-redirect-flows
My nginx default is:
server {
charset UTF-8;
listen 80;
root /srv/www/sitename/;
index index.html;
server_name sitename.com;
location /api/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://sitename.com:8081;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
location / {
try_files $uri.html $uri $uri/ /index.html;
}
My button from Vuejs front end:
completeOrder()
..and uses axios this way:
import axios from 'axios'
export default() => {
return axios.create({
baseURL: 'http://sitename.com:8081/api'
})
}
And set it up here:
import Api from '#/services/Api'
export default {
completeOrder () {
return Api().post('order')
}
}
In the back end it sends:
app.post('/api/order', function (req, res){
rp({
//rp is npm request-promise
uri: BASE_URL + "/redirect_flows",
method: 'POST',
body:JSON.stringify(input_json),
headers: headers
}) // this works and API sends me the response
.then(function(response) {
var str_response =JSON.parse(response);
url = str_response['redirect_flows']['redirect_url']
// url works fine when I paste into a separate browser
res.redirect(url)
})
.catch(function (err) {
console.error(err);
})
})
Everything works up until the point:
res.redirect(url)
..where the Gocardless API response supplies me with the URL which I need to load into a browser.
It looks something like this:
https://pay-sandbox.gocardless.com/flow/RE000156
I think I need to break out of Vuejs's control of the browser via vue-router just long enough to allow the user to call the form with the redirect_url, then come back to the home page of the app again.
Any ideas very welcome!
I think you actually have a JS error. In the then block you instantiate a response, but you use a res variable to redirect.
Try chaging the variable
.then(function(response) {
var str_response = JSON.parse(response);
url = str_response['redirect_flows']['redirect_url']
// url works fine when I paste into a separate browser
response.redirect(url)
})
I am not a Vue.JS expert, so I don't know if that works, try using a vanilla JS redirect to test this feature:
window.location.href = url;
This way, you will be sure that the url works. After that, try checking out a full Vue.JS option.
I have a requirement for basic html template webapp such as:
http://localhost:3000/myapp?param1=hello¶m2=John is called it should return text/html response which looks like this:
<html>
<body>
<p>Nice to see you John. Platform greets you "hello".</p>
</body>
</html>
the name and greeting is templated from param. so template is something like this:
<html>
<body>
<p>Nice to see you {{param1}}. Platform greets you "{{param2}}".</p>
</body>
</html>
I have currently done this in node server using express.js and then the server is exposed publicly via nginx.conf:
server {
listen 80;
# server_name example.com;
location / {
proxy_pass http://private_ip_address:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I was wondering if this could be possible with some plugins or other configuration with bare nginx without hosting the node server on 3000 port.
I was able to solve this using only Nginx to program it using OpenResty's lua module.
The https://github.com/openresty/lua-nginx-module gives ability to program in nginx.conf, where one could use the existing lua libraries such as https://github.com/bungle/lua-resty-template for templating!
myapp.lua:
local template = require("resty.template")
local template_string = ngx.location.capture("/templates/greet.html")
template.render(template_string.body, {
param1 = ngx.req.get_uri_args()["param1"],
param2 = ngx.req.get_uri_args()["param2"]
})
greet.html:
<html>
<body>
<p>Nice to see you {{param1}}. Platform greets you "{{param2}}".</p>
</body>
</html>
nginx.conf:
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
root ./;
server {
listen 8090;
location /myapp {
default_type text/html;
content_by_lua_file ./lua/myapp.lua;
}
}
content_by_lua_file is where the power of openresty comes.
I described the complete process here: https://yogin16.github.io/2018/03/04/nginx-template-engine/
Hopefully, someone would find this helpful.
You can't render file with nginx.
Just send the file with nginx and the rewrite directive then inside the file just include some javascript to replace text content with query parameters
Nginx conf :
location / {
rewrite ^ /static/index.html break;
}
index.html:
<div>My content <span id="name"></span></div>
<script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
document.getElementById("name").textContent = getParameterByName("foo"):
</script>
I'm currently building a web portfolio that combines many smaller web apps that I've made in the past. At the route (/) you find a page with links to these other smaller web apps. For instance, there's a link to route (/board-game) which takes you to the small board-game web app I made in the past.
What I'm struggling with is this. The smaller web app board-game serves it's html, css, and javascript to routes that don't include the prefix route (/board-game). So when a board-game page makes a request for (/css/style.css) nothing is loaded because the content is actually at (/board-game/css/style.css).
My question is this. Is there a way to re-route these requests to the appropriate route? I would like to avoid rewriting any part of these smaller projects. Any suggestions? Thank you.
Also, this is my current nginx.conf file.
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream portfolio {
server portfolio-svc:8080;
}
upstream board-game {
server board-game-svc:8080;
}
server {
listen 80;
location / {
proxy_pass http://portfolio/;
}
location /board-game {
proxy_pass http://board-game/;
}
}
}
You need to rewrite the path as part of the location, for example:
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream portfolio {
server portfolio-svc:8080;
}
upstream board-game {
server board-game-svc:8080;
}
server {
listen 80;
location = / {
proxy_pass http://portfolio/;
}
location = /board-game {
proxy_pass http://board-game/;
rewrite ^(.*)board-game(.*)$ http://board-game/$2 permanent;
sub_filter /css/ /board-game/css/
}
}
}
You might have to play with the matching a bit, but that's the general idea.
I have a .gz file located at /public/files/update.tar.gz. I would like to serve it for downloading using the route /ud/files/update.tar.gz. I would like to do it as static content and also with route (as some files will have a dynamic generated route).
I've tried the following for static (Actually achieved with nginx wich maybe is even better):
main.use('/ud/files', express.static(path.join(__dirname, 'public/files')));
Here I get the error:
Error: No default engine was specified and no extension was provided. at new View (bla bla)
And for dynamic url at /ud/files/tX2r8z/update.tar.gz:
router.get('/ud/files/:s/:file', function(req, res) {
checkSg(req.params.s, function(err) {
if(!err) {
res.download("/public/files/" + req.params.file, req.params.file); 'also tried sendFile()
} else {
res.send(404);
}
});
});
Here I get two errors toghether:
Error: Forbidden at SendStream.error (bla bla)
Error: No default engine was specified and no extension was provided. at new View (bla bla)
Any ideas?
Ok, found the solution: the first one it was a configuration problem as nginx was rewriting the path in order to serve the file itself (Right now I'm wondering why it wasn't served by nginx and the request was sent to node...):
location ~ ^/(ud\/files)/ {
rewrite ^/ud\/files(/.*)$ $1 last;
root /mnt/data/public/files;
gzip_static on;
add_header Cache-Control public;
}
location / {
proxy_pass http://127.0.0.1:3000;
}
So node was seeing a GET /updates.tar.gz
The second one has been solved as stated in this thread:
res.download(path.resolve("public/files/" + req.params.file));