Laravelsubdomain - 404 on both main and sub domains - subdomain

I am working on a project which needs a subdomain and a main domain.
So I wrote some changes on the boot function of RouteServiceProvider, as mentioned below. It's working fine on localhost, but on the server, both main and subdomain return 404.
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
// Main domain routes.
Route::domain(config('constants.app_url'))
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
// SubDomain Routes.
Route::domain('users.'.config('constants.app_url'))
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web_user.php'));
});
}

Related

Html Widget src appears and then disappears on refresh

My HTML Script tag has a src, but then the div id to display the widget appears and then disappears on refresh. The DIV is still there but its not bringing in the source.
I don't know why as I get no error message in the Javascript debugger.
One weird thing is it doesn't disappear in Localhost but ONLY in Azure.
Refresh the page to re-produce the issue.
I'm using Blazor .NET Core, and the widget is at:
Site:
https://markstest1.azurewebsites.net/
Source file:
https://www.climatelevels.org/graphs/js/co2.php?theme=dark-unica&pid=2degreesinstitute
Source Code
Startup.cs (CORS added for site). One site is http.
Could that be an issue?
public class Startup
{
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(//name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("https://www.climatelevels.org", "http://www.2degreesinstitute.org")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
DIV Tag with id to source file. Razor file.
<div id="co2-widget-container"></div>
_Host.cshtml file with tags
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="_framework/blazor.server.js"></script>
<script src="https://www.climatelevels.org/graphs/js/co2.php?theme=dark-unica&pid=2degreesinstitute"></script></script>
Seems to be loading now correctly. The answer was that Blazor was starting too early and canceling the javascript loads in the _Host file. It seems I had to add the tag
<script src="_framework/blazor.server.js" autostart="false"></script>
to the Blazor script file so it doesn't start too quickly and let's the startup file initiate Blazor instead. Then mutate the src URL into a Blazor.start() call after DOMContentLoaded is loaded.
<script>document.addEventListener("DOMContentLoaded", function () {
Blazor.start().then(function () {
var customScript = document.createElement('script');
customScript.setAttribute('src', '//www.website...');
document.head.appendChild(customScript);
});
});</script>
Resource link used:
https://github.com/dotnet/aspnetcore/issues/22643
https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-5.0

AngularJs Dynamic/Multiple HTML Templates

I'm working on an AngularJs/MVC app with Web API etc. which is using a CDN. I have managed to whitelist two URLs for Angular to use, a local CDN and a live CDN (web app hosted in Azure).
I can successfully ng-include a template from my local CDN domain, but the problem arises when I push the site to a UAT / Live environment, I cant be using a template on Localhost.
I need a way to be able to dynamically get the base url for the templates. The location on the server will always be the same, eg: rooturl/html/templates. I just need to be able to change the rooturl depending on the environment.
I was thinking if there was some way to store a global variable, possibly on the $rootScope somewhere that I can get to when using the templates and then set that to the url via Web API which will get return a config setting.
For example on my dev machine the var could be http://Localhost:52920/ but on my uat server it could be https://uat-cdn.com/
Any help would be greatly appreciated as I don't want to store Js, css, fonts etc on the CDN but not the HTML as it feels nasty.
Thanks I'm advance!
I think it's good practice to keep environment and global config stuff outside of Angular altogether, so it's not part of the normal build process and is harder to accidentally blow away during a deploy. One way is to include a script file containing just a single global variable:
var config = {
myBaseUrl: '/templates/',
otherStuff: 'whatever'
}
...and expose it to Angular via a service:
angular.module('myApp')
.factory('config', function () {
var config = window.config ? window.config : {}; // (or throw an error if it's not found)
// set defaults here if useful
config.myBaseUrl = config.myBaseUrl || 'defaultBaseUrlValue';
// etc
return config;
}
...so it's now injectable as a dependency anywhere you need it:
.controller('fooController', function (config, $scope), {
$scope.myBaseUrl = config.myBaseUrl;
}
Functionally speaking, this is not terribly different from dumping a global variable into $rootScope but I feel like it's a cleaner separation of app from environment.
If you decide to create a factory then it would look like this:
angular.module('myModule', [])
.factory('baseUrl', ['$location', function ($location) {
return {
getBaseUrl: function () {
return $location.hostname;
}
};
}]);
A provider could be handy if you want to make any type of customization during config.
Maybe you want to build the baseurl manually instead of using hostname property.
If you want to use it on the templates then you need to create a filter that reuses it:
angular.module('myModule').filter('anchorBuilder', ['baseUrl', function (baseUrl) {
return function (path) {
return baseUrl.getBaseUrl() + path;
}
}]);
And on the template:
EDIT
The above example was to create links but if you want to use it on a ng-include directive then you will have a function on your controller that uses the factory and returns the url.
// Template
<div ng-include src="urlBuilder('path')"></div>
//Controller
$scope.urlBuilder = function (path) {
return BaseUrl.getBaseUrl() + path;
};
Make sure to inject the factory in the controller

AngularJS and Laravel 4 routing conflict in HTML5 mode

I would like to remove the # hash from URLs using Angularjs' $locationProvider.html5Mode(true).
Example: The address bar displays http://localhost/shop instead of http://localhost/#/shop.
Everything works well untill I refresh a page. If i refresh, the following Laravel Route (defined in routes.php) is accesed
Route::resource('shop', 'ShoppingController')
not the AngularJS Route (defined in app.js)
$routeProvider.when('/shop', {
templateUrl: 'templates/shop.html',
controller: 'ShoppingController'
});
My Code:
routes.php (Laravel Routes)
Route::get('/', function() {
return View::make('index');
});
Route::resource('shop', 'ShoppingController');
app.js (AngularJS Routes)
var app = angular.module('shoppingApp',['ngRoute','SharedServices']);
app.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/shop', {
templateUrl: 'templates/shop.html',
controller: 'ShoppingController'
});
$routeProvider.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
});
My directory structure:
Project
/app
/...
/views
-index.php (single page application file)
-routes.php (Laravel routes)
/public
/...
/js
-angular.js
-app.js
-index.php (Laravel index file)
Tried Solutions:
Rewrite the htaccess file so that all requests are redirected to index.php (the single page application file, from where AngularJS would take over the routing). Problem: In this way the Laravel route (Route::resource('shop', 'ShoppingController'); - necessary for interaction with the database) becomes inaccessible to the AngularJS $http service:
app.js
app.controller("ShoppingController", function($scope, $http) {
$http.get('/shop', { cache: true}).
success(function(data, status) {
$scope.items = data
}).
error(function(data, status) {
console.log('Status: ' + status);
});
});
Question:
How can I solve the routing problem, so that the AngularJS route, not the Laravel Route gets accessed if I refresh localhost/shop?
From what I read, it seems like Laravel is reading the modified route when you refresh the page. In this case, you should make Laravel continue to make the original view even if it would otherwise be a 404 redirect.
Try adding the following somewhere on the Laravel side (Ex. routes.php)
App::missing(function($exception)
{
return View::make('index');
});
Note: You might want to have AngularJS's routing use .otherwise to handle pages that are not found.
A better solution is to redirect this way:
'Redirect::to('/#/' . Request::path())'
When you refresh or go to the URI directly:
'Request::path()': returns the requested URI i.e.
('/shop/categories/electronics');
AngularJS in 'html5Mode' still responds to the '#/' prefix;
If angular detects the prefix when in HTML5 mode it will remove the prefix for you.
Final solution:
App::missing(function($exception) {
return Redirect::to('/#/' . Request::path());
});
If you are using Laravel 5 then go to app/Exception/Handler.php and place the code below:
public function render($request, Exception $e)
{
if($e instanceof NotFoundHttpException)
{
return Redirect::to('/#/' . Request::path());
}
return parent::render($request, $e);
}
If you wana have more than one single page application running in html5mode or just have another use for App::missing inside a Laravel app you migh use a rewrite rule like this:
#Redirect base url of AngularJS app in html5mode
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/path/.+$
RewriteRule ^(path)/(.*) /path/#/$2 [R=301,L,NE]
I have another solution which I found quite useful. Rather than just making home page view, I pass in the URI to the home page, which will get checked by a controller and redirect accordingly (the Angular way). This means that if you are on myapp.com/about and you refresh, instead of taking you home, it takes you back to the page you were currently on.
routes.php: Notice that I have a URI wildcard that I pass in as an argument to the callback function, then as a variable to the view.
// Note that this must be on the bottom of your routes file because
// if you have any registered route with a similar pattern
// it will get caught by this route and never reach any registered routes you might have
Route::get('{slug}', function($slug){
return View::make('index', compact('slug'));
});
// These routes will never get hit, so move them above Route::get('{slug}')
Route::get('about', function(){...});
Route::get('contact', function(){...});
index.blade.php:
<html ng-app"myApp">
<head>
...
</head>
<body>
<!--Check if there is a variable named $slug that is set-->
<!--If it is, set hidden input with ng-model-->
#if(isset($slug))
<input type="hidden" value="{{slug}}" ng-model="slug" ng-controller="RedirectController">
#endif
<div ng-view></div>
</body>
</html>
app.js
angular.module('myApp', [])
.controller('RedirectController', ['$location', '$scope', function ($location, $scope) {
// If slug is set, redirect to that slug
if ($scope.slug) {
$location.path('/' + $scope.slug);
}
}]);
For Laravel 4.x or 5.x i use this simple and nice trick and there is no need to change .htaccess file. this trick is very simple and works for me. it doesn't redirect URL and user will stay on same URL when refresh page and page will refresh:
Route::get('dashboard/{all?}', function(){
return view('main.index');
});
here my dashboard app is my SPA. this way we can resolve 404 errors pages too.

URL redirect in ServiceStack loginpage

In my apphost.cs file I have defined unauthorized requests to open login.cshtml.
SetConfig(new EndpointHostConfig
{
CustomHttpHandlers =
{
{HttpStatusCode.NotFound, new RazorHandler("NotFound")},
{HttpStatusCode.Unauthorized, new RazorHandler("login")},
}
});
I'm running the project self hosted. I have deployed the project to a server (Debian+Apache: ProxyPass to http://127.0.0.1:2008).
My problem is that the redirect link(querystring) links back to http://127.0.0.1:2008/People.
http://servername/login?redirect=http://127.0.0.1:2008/People
How can I override the redirect url to point to http://servername/People?
Try specifying the server url you wish to use in your config, e.g:
SetConfig(new HostConfig {
WebHostUrl = "http://servername/"
});

Remote method is getting called twice using EasyXDM interface (for cross domain IFrame communication) method when there are 2 channels

I have got 2 IFrames on a host Page and wanted to set up the bi-directional channel between Host page and IFrames. For that I used easyXDM Interface class and was able to set up the communication between the host page and iFrames.
Host page is on one domain and all the IFrames are on the different domain but the all the 3 IFrames are on the same domain.
I had set up 2 channels on the host page using easyXDM interface class and specified the required properties like what local methods , remote methods etc..
Host page has got local method called publish, and this publish method is remote on all the IFrames.
The problem I am getting is that when the publish method is called from one IFrame , the publish is called for all the IFrames channel on the host page.
Code on the Host page looks like :
channel1 = new easyXDM.Interface(
{
local: "/name.html",
remote: "PathToIFrame1.html",
container: document.getElelmentById('Div1')
}
, {
remote: {
receive: {}
},
local: {
publish: { method: function () { } }
}
}
);
channel2 = new easyXDM.Interface(
{
local: "/name.html",
remote: "PathToIFrame2.html",
container: document.getElelmentById('Div2')
}
, {
remote: {
receive: {}
},
local: {
publish: { method: function () { } }
}
}
);
and code on IFrame side looks like :
remote = new easyXDM.Interface({},
{
remote: {
publish: {
isVoid: true
}
},
local: {
Receive: {
isVoid: true,
method: function (a, b) {
}
}
}
});
}
and when publish method is called from IFrame side , publish methods of channel1 and channel2 (on the host side ) both gets called.
Can someone please suggest what could be wrong here.