I am trying to use PhantomJS and angular-seo (https://github.com/steeve/angular-seo) to make my app crawlable.
As I am not using hashbangs, I've added the following meta tag to my app's header:
<meta name="fragment" content="!" />
In my main controller, I trigger $scope.htmlReady when the content is fully loaded:
$scope.$on('$viewContentLoaded', function() {
$scope.htmlReady();
});
I have loaded the seo module properly and while my server's app listens on port 4000 (I use an express server), I launch phantomJS on port 4040 with the following command:
phantomjs --disk-cache=no ./bin/angular-seo-server.js 4040 http://127.0.0.1:4000
If I check how things are working for the homepage with a simple curl 'http://127.0.0.1:4040/?_escaped_fragment_=' I get the correct HTML rendered properly.
But if I try a different route like http://127.0.0.1:4040/test?_escaped_fragment_= I only get <html><head></head><body></body></html> while http://127.0.0.1:4000/test works fine.
How can I make sure all my pages are indexed and not only my homepage?
Related
I am trying to deploy a Web App using Google AppScript with multiple views. I have an appCover.html with a few buttons and each button redirects to a different page. The app cover (or homepage) loads flawlessly but when I click on any of the buttons I get the error in the console:
Refused to display
'https://script.google.com/macros/s/sriptID/dev?v=newPage'
in a frame because it set 'X-Frame-Options' to 'sameorigin'
I have looked into Google's developer resources and all the references I found tell to add the XFrameOptionsMode.ALLOWALL. So I did but still no success. This is the function that is rendering each page:
function render(file, argsObject) {
var tmp = HtmlService.createTemplateFromFile(file);
if (argsObject) {
var keys = Object.keys(argsObject);
keys.forEach(key => {
tmp.key = argsObject[key];
});
}
return tmp.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}
Right now I am testing the deployment so I get /dev at the end when retrieving the URL and try to route with a parameter like /dev?v=newPage. Does it make a difference tying to access these pages when testing the deployment versus deploying itself?
It's a personal app so I'm the only user.
Any other ideas on how to solve this?
The problem is that you are using the dev version
Deploy your Webapp as an exec version
https://script.google.com/macros/s/XXX/scriptID
and then build your URL as
https://script.google.com/macros/s/sriptID/exec?v=newPage
Once you deploy your Webapp as a exec version, the method ScriptApp.getService().getUrl() will return you the corerct (exec) URL which you can use as a variable to dynamically build your redirection to different pages / views.
I'm trying to familiarize myself with the concept of using script tags. I'm making a ruby on rails app that does something as simple as alert "Hi" when a customer visits a page. I am testing this public app on a local server and I have the shopify_app gem installed. The app has been authenticated and I have access to the store's data. I've viewed the Shopify API documentation on using script tags and I've looked at the Shopify Embedded App example that Shopify has on GitHub. The documentation details the properties of a script tag and gives examples of script tags with their properties defined, but doesn't say anything about where to place the script tag in an application, or how to configure an environment so that the js file in the script tag will go through.
I've discovered that a js file being added with a script tag will only work if the js file is hosted online, so I've uploaded the js file to google drive. I have the code for the script tag in the index action of my HomeController (the default page for the app). This is the code I'm using:
def index
if response = request.env['omniauth.auth']
sess = ShopifyAPI::Session.new(params[:shop], response[:credentials][:token])
session[:shopify] = sess
ShopifyAPI::Base.activate_session(sess)
ShopifyAPI::ScriptTag.create(
:event => "onload",
:src => "https://drive.google.com/..."
)
end
I think the problem may be tied to the request.env. The response is not being read as request.env[omniauth.auth] and I believe that the response coming back as valid may be required for the script tag to go through.
The method that I tried above is from the 2nd answer given in this topic: How to develop rails app for shopify with ScriptTags.
The first answer suggested using this code:
ShopifyAPI::Base.site = token
s = ShopifyAPI::ScriptTag.create(:events => "onload",:src => "your javascript url")
However, it doesn't say where to place both lines of code in a rails application. I tried putting the second line in a js file in my rails application, but it did not work.
I don't know if I'm encountering problems because I'm running the app on a local server or if there is something missing from the configuration of my application.
I'd appreciate it if anyone could point me in the right direction.
Try putting something like this in config/initializers/shopify_app.rb
ShopifyApp.configure do |config|
config.api_key = "xxx-xxxx-xxx-xxx"
config.secret = "xxx-xxxx-xxx-xxx"
config.scope = "read_orders, read_products"
config.embedded_app = true
config.scripttags = [
{event:'onload', src: 'https://yourdomain.herokuapp.com/javascripts/yourjs.js'}
]
end
Yes, you are correct that you'll need the js file you want to include for your script tag publicly available - if you are using localhost for development look into ngrok.
Do yourself the favor of ensuring your callbacks use SSL when interacting with the Shopify API (i.e. configure your app with https://localhost/ as a callback setting in the Shopify app settings). I went through the trouble of configuring thin as the web server locally with a self-signed SSL certificate.
With a proper set up you should be able to debug why the response is failing the omniauth check.
I'm new to the Shopify API(s), but not Rails. Their documentation leaves a lot to be desired.
Good luck to you sir,
I'm having troubles with an app when loaded on my deployment server.
I'm using AngularJS 1.4.x and following the scheme proposed by Angular-Seed template for routing and configuration: https://github.com/angular/angular-seed
Everything works fine on local (Apache) and on another remote web server (Apache) (a free hosting service). Routing works and pages load like expected. In the remote server i can experience some little hangs when loading a template not loaded before but i think it's normal.
The problem is on my official deployment server (Apache):
Instead of loading routes templates it load recursively the index.html inside it self resulting in an stack exceeded error from the browser after few seconds and the halting of the page.
Sometimes it doesn't and load the page like expected, but after two or three routes it start loading index.html recursively instead of the template requested.
In most cases, however, at the first route triggered by link or event the page hangs loading recursively index.html inside itself.
Like in angular-seed i have a single index.html with a <div ng-view></div> tag for content.
No problem on local and in the another free web server.
I've tried even to use ui.router and his states pattern instead of ng-router.
No more stack exceeded because after the first index.html loaded inside index.html at the <div ng-view> it stops the recursion.
With ui.router, still no problem in local or in the other free web server. The app do what expected loading all the states/route.
There is some apache configuration or something i must check on the server?
The deployment server is a dedicated server so i can have access to everything.
Thanks for help!
EDIT:
Here Apache modules of the three server:
Local server Apache modules:
core
http_core
mod_access_compat
mod_actions
mod_alias
mod_allowmethods
mod_auth_basic
mod_auth_digest
mod_auth_form
mod_authn_anon
mod_authn_core
mod_authn_dbd
mod_authn_dbm
mod_authn_file
mod_authn_socache
mod_authnz_ldap
mod_authz_core
mod_authz_dbd
mod_authz_dbm
mod_authz_groupfile
mod_authz_host
mod_authz_owner
mod_authz_user
mod_autoindex
mod_bucketeer
mod_buffer
mod_cache
mod_cache_disk
mod_case_filter
mod_case_filter_in
mod_cern_meta
mod_cgi
mod_cgid
mod_charset_lite
mod_dav
mod_dav_fs
mod_dbd
mod_deflate
mod_dir
mod_dumpio
mod_echo
mod_env
mod_expires
mod_ext_filter
mod_file_cache
mod_filter
mod_headers
mod_include
mod_info
mod_lbmethod_bybusyness
mod_lbmethod_byrequests
mod_lbmethod_bytraffic
mod_lbmethod_heartbeat
mod_log_config
mod_log_debug
mod_logio
mod_mime
mod_mime_magic
mod_negotiation
mod_perl
mod_php5
mod_proxy
mod_proxy_ajp
mod_proxy_balancer
mod_proxy_connect
mod_proxy_express
mod_proxy_fcgi
mod_proxy_ftp
mod_proxy_http
mod_proxy_scgi
mod_ratelimit
mod_remoteip
mod_reqtimeout
mod_request
mod_rewrite
mod_sed
mod_session
mod_session_cookie
mod_session_dbd
mod_setenvif
mod_slotmem_shm
mod_so
mod_socache_dbm
mod_socache_memcache
mod_socache_shmcb
mod_speling
mod_ssl
mod_status
mod_substitute
mod_suexec
mod_unique_id
mod_unixd
mod_userdir
mod_usertrack
mod_version
mod_vhost_alias
prefork
util_ldap
Remote server Apache modules:
core
http_core
mod_actions
mod_alias
mod_asis
mod_auth_basic
mod_authn_default
mod_authn_file
mod_authz_default
mod_authz_groupfile
mod_authz_host
mod_authz_user
mod_av_htaccess
mod_cgi
mod_deflate
mod_dir
mod_env
mod_expires
mod_fastcgi
mod_filter
mod_include
mod_log_config
mod_logio
mod_mime
mod_negotiation
mod_php5
mod_rewrite
mod_setenvif
mod_so
mod_status
mod_version
mod_vhost_alias
parser
prefork
Production server Apache modules:
core
http_core
mod_actions
mod_alias
mod_auth_basic
mod_authn_default
mod_authn_file
mod_authz_default
mod_authz_groupfile
mod_authz_host
mod_authz_user
mod_autoindex
mod_cgi
mod_dir
mod_env
mod_expires
mod_filter
mod_headers
mod_include
mod_log_config
mod_logio
mod_mime
mod_negotiation
mod_proxy
mod_proxy_ajp
mod_proxy_balancer
mod_proxy_connect
mod_proxy_ftp
mod_proxy_http
mod_proxy_scgi
mod_rewrite
mod_setenvif
mod_so
mod_ssl
mod_status
mod_suexec
mod_unique_id
mod_userdir
prefork
Could be the lack of mod_vhost_alias be related to issue?
I've read that mod_userdir will overwrite mod_vhost_alias but it's the only module missing in my production server that concern resolution of files and that is present on local and remote free configuration...
I'll try to rebuild apache and include that module in the next few days and then test.
After some checking by the support team of my hosting provider we have identified the problem.
It was related to some false positive matching by ModSecurity apache module.
I had to disable following rules id:
981242
981243
981245
981246
981257
And this maybe not strictly related rule that got triggered during testing:
970901
All rules are related to MySQL injection preventing.
Now app works as expected.
Hope it can be of anyhelp for someone.
Thank you all for support, tips and advices!
I am using page.js in an HTML+CSS+JS app.
The routes work perfectly in browser, even using the "phonegap serve" and accessing my_ip:3000.
But when I try to load it in my phoneGap Developer (in an Android phone), only the first route loads (if I try to navigate through the app links, I get only blank screens).
When using page.js in mobile apps (with cordova, phonegap or cocoon), just use:
page( { dispatch: false } )
page( '/' )
Instead of:
page()
You can replace '/' with the first route that you want your app to start with.
In details:
Normally, in a web app, you use page() to start the routing process and, of course, it will identify which route is being requested and call the correspondent function.
Since in mobile we don't have an URL request, we disable this identification process with dispatch: false and pass a default start route.
I am having a tough time figuring out how to access a page loaded in an iframe from the outer page. Both pages are local files, and I'm using Chrome.
I have an outer page, and many inner pages. The outer page should always display the page title for the inner page (it makes sense in my application, perhaps less so in this stripped-down example). This works without any problem in AppJS, but I've been requested to make this app work directly in the browser. I'm getting the error "Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.".
I think this is due to Chrome's same origin policy regarding local files, but that hasn't helped me fix the problem directly. I can work around the issue in this stripped-down example by using the window.postMessage method per Ways to circumvent the same-origin policy. However, going beyond this example, I also want to manipulate the DOM of the inner page from the outer page, since this will make my code much cleaner - so posting messages won't quite do the job.
Outer Page
<!DOCTYPE html>
<html>
<head>
<meta name="viewport">
</head>
<body>
This text is in the outer page
<iframe src="html/Home.html" seamless id="PageContent_Iframe"></iframe>
<script src="./js/LoadNewPage.js"></script>
</body>
</html>
Inner Page
<!DOCTYPE html>
<html>
<head>
<title id="Page_Title">Home</title>
<meta name="viewport">
</head>
<body>
This text is in the inner page
</body>
</html>
JavaScript
var iFrameWindow = document.getElementById("PageContent_Iframe").contentWindow;
var pageTitleElement = iFrameWindow.$("#Page_Title");
Per Is it likely that future releases of Chrome support contentWindow/contentDocument when iFrame loads a local html file from local html file?, I tried launching Chrome with the flag
--allow-file-access-from-files
But there was no change in the results.
Per Disable same origin policy in Chrome, I tried launching Chrome with the flag
--disable-web-security
But again there was no change in the results.
Per What does document.domain = document.domain do?, I had both pages run the command
document.domain = document.domain;
This resulted in the error "Blocked a frame with origin "null" from accessing a frame with origin "null". The frame requesting access set "document.domain" to "", but the frame being accessed did not. Both must set "document.domain" to the same value to allow access."
For fun, I had both pages run the command
document.domain = "foo.com";
This resulted in the error "Uncaught Error: SecurityError: DOM Exception 18".
I'm floundering. Any help from more knowledgeable people would be fantastic! Thanks!
I'm sorry to say you that I've tried during weeks to solve this issue (I needed it for a project) and my conclusion is that it's not possible.
There are a lot of problems arround local access through javascript with chrome, and some of them can be solved using --allow-file-access-from-files and --disable-web-security, including some HTML5 offline features, but I definitely think there's no way to access local files.
I recomend you not to lose your time trying to circunvend this and to try to post messages wich you can interpret into the inner pages, so you can do the DOM modifications there.
Per our discussion in my cube just a minute ago :)
I hit this same problem (Ajax post response from express js keeps throwing error) trying to get an AJAX post request to work correctly.
What got me around it is not running the file directly off the file system but instead running it from a local server. I used node to run express.js. You can install express with the following command: npm install -g express
Once that is accomplished, you can create an express project with the following command: express -s -e expressTestApp
Now, in that folder, you should see a file named app.js and a folder named public. Put the html files you wish to work with in the public folder. I replaced the file app.js with the following code:
var express = require('/usr/lib/node_modules/express');
var app = express();
app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
});
app.use(express.bodyParser());
app.use(express.static('public'));
app.listen(5555, function() { console.log("Server is up and running"); });
Note, the require line may be different. You have to find where your system actually put express. You can do that with the following command: sudo find / -name express
Now, start the express web server with the following command: node app.js
At this time, the webserver is up and running. Go ahead and open a browswer and navigate to your ip address (or if you're on the same machine as your server, 127.0.0.1). Use the ip address:portnumber\filename.html where port number is the 5555 in the app.js file we created.
Now in that browser, you shouldn't (and didn't when we tested it) have any of these same problems anymore.
file:// protocol and http:// protocol make things to behave very differently in regards to iframes. I had the same issues you describe with an app on PhoneGap which uses file protocol to access all local files within the local assets/www folder.
If seems that modern browsers prevent the display of "local" files using the file protocol in iframes for security reasons.
We ended up dumping iframes and just using divs as "viewports". Fortunately the overall size of our app was not that big so we managed to load everything in a single page.